【问题标题】:How can I mock a method that returns a Task<IList<>>?如何模拟返回 Task<IList<>> 的方法?
【发布时间】:2016-07-24 21:02:52
【问题描述】:

我正在尝试对返回任务的方法进行单元测试>:

void Main()
{
    var mockRepo = new Mock<IRepository>();
    mockRepo.Setup(x => x.GetAll()).Returns(new List<MyModel>() { new MyModel { Name = "Test" } });  // works

    mockRepo.Setup(x => x.GetAllAsync()).Returns(Task.FromResult(new List<MyModel>() { new MyModel { Name = "Test" } }));  // error

    var result = mockRepo.Object.GetAll();
    result.Dump();
}

public interface IRepository
{
    Task<IList<MyModel>> GetAllAsync();
    IList<MyModel> GetAll();
}

public class MyModel
{
    public string Name { get; set; }
}

但是Task返回方法会产生编译错误:

CS1503 参数 1:无法从 'System.Threading.Tasks.Task' 至 'System.Threading.Tasks.Task'

我做错了什么?

【问题讨论】:

    标签: c# unit-testing asynchronous task moq


    【解决方案1】:

    您可以使用 ReturnsAsync 方法:

    IList<MyModel> expected = new List<MyModel>() { new MyModel { Name = "Test" }};
    mockRepo.Setup(x => x.GetAll()).ReturnsAsync(expected);
    

    【讨论】:

    • 谢谢,刚刚找到了,
    【解决方案2】:

    发布到很快,发现 Moq 有 ReturnsAsync 方法。

    mockRepo.Setup(x => x.GetAllAsync()).ReturnsAsync((new List<MyModel>() { new MyModel { Name = "Test" } });  
    

    工作正常。

    【讨论】:

      【解决方案3】:

      只需将您的列表转换为 IList:

      Task.FromResult((IList<MyModel>) new List<MyModel>() { new MyModel { Name = "Test" } })
      

      或者定义通用参数:

      Task.FromResult<IList<MyModel>>(new List<MyModel>() { new MyModel { Name = "Test" } })
      

      【讨论】:

      • 是的,谢谢,这行得通。但我找到了一个更优雅的解决方案,使用 ReturnsAsync 方法。
      【解决方案4】:

      将结果投射到IList

      Task.FromResult(<strong>(IList)</strong>new List() { new MyModel { Name = "Test" } });

      【讨论】:

        【解决方案5】:

        你的问题是你的方法应该返回Task&lt;IList&gt; 而你返回Task&lt;List&gt; 你不能这样做——它们是不同的类型,它们不支持逆变或协方差。你需要转换你的返回类型

         mockRepo.Setup(x => x.GetAllAsync()).Returns(Task.FromResult((IList<MyModel>)new List<MyModel>() { new MyModel { Name = "Test" } }));
        

        【讨论】:

        • 不,你的结论是错误的。再次阅读我的问题。
        • 我很确定它不是,因为我的答案与其他人的答案完全相同,而且它显然有效 - 原因是泛型协变和逆变。无论如何,接受的答案是正确的。
        • 不,你的陈述:“你的问题是你的方法应该返回 Task 而你返回 Task 你不能这样做”是错误的。这就是我反对的。正如问题中所述,它实际上是返回 IList 的任务。
        • Task.FromResult(new List() { new MyModel { Name = "Test" } }) 这段代码,在您的 .Returns() 中导致返回值 Task 不是任务
        猜你喜欢
        • 1970-01-01
        • 2016-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-14
        • 2021-04-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多