1

I have the following method, that I'm trying to write some unit tests

public async Task<ShareClient> CreateFileShare(string shareName)
    {
        if (!ShareNameValidator.IsValid(shareName))
        {
            throw new ArgumentException("Invalid share name.");
        }

        ShareClient shareFileClient = _shareServiceClient.GetShareClient(shareName.ToLowerInvariant());
        if (await shareFileClient.ExistsAsync())
        {
            throw new ShareExistsException("Share already exists.");
        }
        await shareFileClient.CreateAsync();

        return shareFileClient;
    }

this is part of a helper class, and all the dependencies you're seeing will be available in run-time. I have 3 nit tests for this. just putting signature, but it's quite straight forward

        public async Task CreateFileShare_ShouldThrowException_WhenShareAlreadyExists()
        public async Task CreateFileShare_ShouldThrowException_WhenInvalidShareName()
        public async Task CreateFileShare_ShouldCreateShare_WhenShareDoesNotExist()

these are xunit tests. first 2 are passing but last one is not. here is the code for last

 [Fact]
 public async Task CreateFileShare_ShouldCreateShare_WhenShareDoesNotExist()
{
        // Arrange
        var responseMock = new Mock<Response<bool>>();
        string validShareName = "valid-share-name";
        responseMock.Setup(x => x.Value).Returns(false);
        _shareClientMock.Setup(x => x.ExistsAsync(It.IsAny<CancellationToken>())).Returns(Task.FromResult(responseMock.Object));
        _shareServiceClientMock.Setup(x => x.GetShareClient(validShareName)).Returns(_shareClientMock.Object);

        // Act
        var createdShareClient = await _fileStorageHelper.CreateFileShare(validShareName);

        // Assert
        createdShareClient.Should().Be(_shareClientMock.Object);
        _shareClientMock.Verify(x => x.CreateAsync(It.IsAny<ShareCreateOptions>(), It.IsAny<CancellationToken>()), Times.Once);
    }

the error message:

 Message: 
Moq.MockException : 
Expected invocation on the mock once, but was 0 times: x => 
x.CreateAsync(It.IsAny<ShareCreateOptions>(), 
It.IsAny<CancellationToken>())
Performed invocations:

Mock<ShareClient:1> (x):

  ShareClient.ExistsAsync(CancellationToken)  => Mock<Response<bool>:1>
  ShareClient.CreateAsync(null, null, CancellationToken)

Mock<Response<bool>:1>:

  Response<bool>.Value

do you see any wrong set up in my mock?

here is another way I tried:

   [Fact]
    public async Task CreateFileShare_ShouldCreateShare_WhenShareDoesNotExist()
    {
        // Arrange
        string validShareName = "validsharename";
        var responseMock = new Mock<Response<bool>>();
        var shareInfoMock = new Mock<ShareInfo>();
        var createResponseMock = new Mock<Response<ShareInfo>>();
        ShareCreateOptions createOptions = new ShareCreateOptions
        {
            QuotaInGB = 100,
        };

        shareInfoMock.DefaultValue = DefaultValue.Mock;
        responseMock.Setup(x => x.Value).Returns(false);
        createResponseMock.Setup(x => x.Value).Returns(shareInfoMock.Object);
        _shareClientMock.Setup(x => x.ExistsAsync(It.IsAny<CancellationToken>())).Returns(Task.FromResult(responseMock.Object));
        _shareClientMock.Setup(x => x.CreateAsync(createOptions, It.IsAny<CancellationToken>())).Returns(Task.FromResult(createResponseMock.Object));
        _shareServiceClientMock.Setup(x => x.GetShareClient(validShareName)).Returns(_shareClientMock.Object);

        // Act
        var createdShareClient = await _fileStorageHelper.CreateFileShare(validShareName);

        // Assert
        createdShareClient.Should().Be(_shareClientMock.Object);
        _shareClientMock.Verify(x => x.ExistsAsync(It.IsAny<CancellationToken>()), Times.Once());
        _shareClientMock.Verify(x => x.CreateAsync(It.IsAny<ShareCreateOptions>(), It.IsAny<CancellationToken>()), Times.Once());
    }        

failing with the same error.

Pamador
  • 158
  • 2
  • 8
  • What do you see when you step through the code while debugging the unit test? – stuartd Feb 07 '23 at 02:37
  • it goes through, it doesn't throw exception. it calls CreateAsync() method on CreateFileShare() method i put it up there, but there is no null object. everything looks fine to me, but is failing with that message – Pamador Feb 07 '23 at 02:40
  • It seems to me like you are trying to verify that CreateAsync gets called with these three types of arguments: It.IsAny(), It.IsAny(). But in your actual code snippet it is called without any arguments: CreateAsync(). I think you need to change the signature to _shareClientMock.Verify(x => x.CreateAsync(), Times.Once()); – ddastrodd Feb 07 '23 at 03:22
  • that's a good point, however, when you mock that method, you need to provide its parameters like so ..It.IsAny, otherwise the setup part will show error An experresion tree may not contain a call or invocation that uses optional arguments – Pamador Feb 07 '23 at 03:38

1 Answers1

0

the problem is in verify part instead of

_shareClientMock.Verify(x => x.CreateAsync(It.IsAny<ShareCreateOptions>(), It.IsAny<CancellationToken>()), Times.Once());

have this

_shareClientMock.Verify(x => x.CreateAsync(It.IsAny<Dictionary<string, string>>(), null, It.IsAny<CancellationToken>()), Times.Once());

the reason for this,as it is saying in the error message is that it calls another overloaded version of CreateAsync method. credit to Nick :)

Pamador
  • 158
  • 2
  • 8