Moq中从未调用过的模拟异步方法

时间:2018-10-13 14:51:48

标签: c# async-await moq xunit.net

我有一个数据库存储库界面:

public interface IDbRepository
{
  Task<T> GetDataAsync<T>(Func<T, bool> filter = null) where T : class;
}

我有以下固定装置:

private List<Status> statusList = new List<Status> {
      new Status { Name="Status A"},
      new Status { Name="Status B"}
    };

var repositoryMock = new Mock<IDbRepository>();
Func<Status, bool> filter = It.IsAny<Func<Status, bool>>();
repositoryMock.Setup(repository => repository.GetDataAsync(filter))
  .ReturnsAsync(
  () =>
  {
    //NEVER CALLED
    if (filter == null)
      return statusList.FirstOrDefault();
    return statusList.FirstOrDefault(filter);
  });

我使用以下测试:

[Fact]
public async Task Repository_GetDataAsync_Filter()
{
  var repository = repositoryTestFixture.Ioc.Resolve<IDbRepository>();
  Func<Status, bool> filter = stat => stat.Name == "Status A";
  var res = await repository.GetDataAsync(filter);
  //await task1.ContinueWith(ctask => Assert.NotNull(ctask.Result));
  Assert.NotNull(res); //ALWAYS NULL!!!
}

我尝试调试,但是该方法从未调用过,因此我总是无法通过测试。

根据@Stephen Cleary,to call Wait()Result不需要测试,而old official way自Visual Studio 2015起已弃用,异步测试是开箱即用。

  

Stephen Cleary•https://stephencleary.com/ 11个月前(2017-11-03   12:22:06 pm)   正如在   页面顶部,此解决方案是为VS2010设计的。 VS2015的作品   开箱即用,异步任务单元测试也可以。

我应该改变什么?

2 个答案:

答案 0 :(得分:3)

使用It.IsAny<>()是不正确的。它只能直接在Setup表达式中使用。不在变量中。

当参数不匹配时,不调用模拟。因此,您将得到null。

ReturnAsync委托中访问传递的参数

var repositoryMock = new Mock<IDbRepository>();
repositoryMock
    .Setup(repository => repository.GetDataAsync(It.IsAny<Func<Status, bool>>()))
    .ReturnsAsync((Func<Status, bool> filter) => {//<-- grab passed argument here
        if (filter == null)
            return statusList.FirstOrDefault();
        return statusList.FirstOrDefault(filter);
    });

答案 1 :(得分:1)

我认为这里的问题是由于您的filter局部变量引起的。通过创建不是表达式的变量,您实际上是在执行It.IsAny调用并返回null。您可以想象,null仅与null函数匹配,这就是为什么看不到ReturnsAsync被击中的原因。

请尝试内联该变量或将其类型更改为Expression<Func<Status, bool>>,看看它是否按预期工作。

您必须始终牢记,模拟设置是使用表达式完成的,因此通常It.IsX调用本身不会执行,只是作为表达式树进行分析和比较。