2

I'm trying to create a set of test methods using Moq to cover the external dependencies. These dependencies are async in nature and I have come across a set of them that when awaited they never return, so I'm not sure what I'm missing.

The test itself is very simple.

[TestMethod]
public async Task UpdateItemAsync()
{
    var repository = GetRepository();
    var result = await repository.UpdateItemAsync("", new object());
    Assert.IsNotNull(result);
}

The GetRepository method above is what sets up the various mock objects including called Setup on them.

private static DocumentDbRepository<object> GetRepository()
{
    var client = new Mock<IDocumentClient>();
    var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();

    client.Setup(m => m.ReplaceDocumentAsync(It.IsAny<Uri>(), It.IsAny<object>(), It.IsAny<RequestOptions>()))
        .Returns(() =>
        {
            return new Task<ResourceResponse<Document>>(() => new ResourceResponse<Document>());
        });

    var repository = new DocumentDbRepository<object>(configuration, client.Object);
    return repository;
}

The code that is under test is listed below and when the line with the await is executed it never returns.

public async Task<T> UpdateItemAsync(string id, T item)
{
    var result = await Client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id), item);
    return result.Resource as T;
}

I'm sure that the error is in the Setup method on the Moq object in the GetRepository method, but I'm not sure what the problem is.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Paul Cavacas
  • 4,194
  • 5
  • 31
  • 60
  • Possible duplicate of [Using Moq to mock an asynchronous method for a unit test](https://stackoverflow.com/questions/20859639/using-moq-to-mock-an-asynchronous-method-for-a-unit-test) – Liam May 01 '18 at 13:29

1 Answers1

8

You need to fix the set up on the async calls

Moq has a ReturnsAsync that would allow the mocked async method calls to flow to completion.

client
    .Setup(_ => _.ReplaceDocumentAsync(It.IsAny<Uri>(), It.IsAny<object>(), It.IsAny<RequestOptions>()))
    .ReturnsAsync(new ResourceResponse<Document>());

You typically want to avoid newing up Tasks manually

Nkosi
  • 235,767
  • 35
  • 427
  • 472