【问题标题】:Moq WebApi async methodMoq WebApi 异步方法
【发布时间】:2017-04-23 20:38:28
【问题描述】:

我是使用 Moq 测试的新手,所以我对 ReturnsAsync 有点困惑。 这是我的测试方法,我期望ReturnsAsync 应该接收将由Setup 中定义的方法返回的类型。我说的对吗?

但似乎 ReturnsAsync 应该有另一个签名 - 它正在寻找 Func 代表。

[TestClass]
public class TourObjectControllerTest
{
    [TestMethod]
    public async Task GetTourObjects()
    {
        var mockService = new Mock<ITourObjectService>(MockBehavior.Default);
        mockService.Setup(x => x.GetAll()).ReturnsAsync(new Task<IEnumerable<TourObjectDTO>>);
        var controller = new TourObjectController(mockService.Object);
        var result = await controller.Get();
        Assert.IsNotNull(result);
        Assert.AreSame(typeof(TourObjectViewModel), result);
    }
}

待测方法:

public async Task<IEnumerable<TourObjectViewModel>> Get()
{
    IEnumerable<TourObjectViewModel> viewmodel = null;
    try
    {
        var tourobjects = await _tos.GetAll();
        viewmodel = Mapper.Map<IEnumerable<TourObjectViewModel>>(tourobjects);
    }
    catch (Exception ex)
    {
        Log.ErrorFormat("Method:{0} <br/> Error: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
    }
    return viewmodel;
}

【问题讨论】:

  • 智能感知怎么说? (我假设你在 VS 中工作。)
  • @KennethK.,它说 Task> 不能分配给类型 Func>

标签: c# unit-testing asp.net-web-api moq


【解决方案1】:

传递一个实际结果。

假设ITourObjectService.GetAll() 返回Task&lt;IEnumerable&lt;TourObjectDTO&gt;&gt;

例如

[TestClass]
public class TourObjectControllerTest
{
    [TestMethod]
    public async Task GetTourObjects()
    {
        var fakeData = new List<TourObjectDTO>() {
            new TourObjectDTO { ... }
        };
        var mockService = new Mock<ITourObjectService>(MockBehavior.Default);
        mockService.Setup(x => x.GetAll()).ReturnsAsync(fakeData);
        var controller = new TourObjectController(mockService.Object);
        var result = await controller.Get();
        Assert.IsNotNull(result);
        Assert.IsTry(typeof(IEnumerable<TourObjectViewModel>).IsAssignableFrom(result.GetType());
    }
}

【讨论】:

  • 如果我错了请纠正我,起订量生成 IEnumerable 类型的随机数据?
  • 不,它没有。不是没有一些扩展或插件
  • 那么,这如何模拟存储库/服务行为?
  • 您正在模拟服务并提供一些虚假数据以在调用模拟成员时返回。
  • 测试失败,即使有实际结果 - Assert.IsNotNull() 中的错误
【解决方案2】:

ReturnsAsync() 应该将返回值作为参数,而不是 Task&lt;TReurnValue&gt;。例如,接下来的 2 行代码是相等的(按行为):

mockService.Setup(x => x.GetAll()).ReturnsAsync(new List<TourObjectDTO>());
mockService.Setup(x => x.GetAll()).Returns(Task.FromResult(new List<TourObjectDTO>()));

您需要将new List&lt;TourObjectDTO&gt;() 替换为您想要在模拟测试中检索的测试数据。例如,您可以只创建几个测试值:

var testData = new [] { new TourObjectDTO(1, "test1"), new TourObjectDTO(2, "test2") };
mockService.Setup(x => x.GetAll()).ReturnsAsync(testData);

或根据需要创建假数据生成器。

请注意,ReturnsAsync() 仅适用于返回 Task&lt;T&gt; 的方法。对于只返回Task 的方法,可以使用.Returns(Task.FromResult(default(object)))

【讨论】:

  • 是的,GetAll 方法返回 Task>
  • @andrey.shedko 好的,然后只需将此方法的预期值作为 ReturnsAsync 的参数传递,或者像上面的代码一样将 Returns 与 Task.Result 一起使用。
猜你喜欢
  • 2016-08-04
  • 2015-02-13
  • 2016-04-16
  • 2015-06-25
  • 1970-01-01
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多