【问题标题】:Moq - mocking LINQ When & FirstOrDefaultMoq - 模拟 LINQ When & FirstOrDefault
【发布时间】:2016-03-20 04:41:24
【问题描述】:

我有以下代码,我正在尝试模拟它,但我的单元测试失败了。

代码:

await _someDataRepository.GetSomeDataAsync(false)
                         .Where(r => r.Code == statusCode)
                         .FirstOrDefault();

模拟:

Mock<SomeDataRepository> _someDataRepositoryMock = new Mock<SomeDataRepository>();

_someDataRepositoryMock.Setup(s => s.GetSomeDataAsync(It.IsAny<bool>()))
                       .Returns<List<Domain.Student.Entities.SectionRegistrationStatusItem>>(
                           i => Task.FromResult(
                               i.Where(sr => sr.Code == It.IsAny<string>())
                           )
                       );

如何模拟链式语句?

【问题讨论】:

  • 请注意,您可以将谓词传递给FirstOrDefault,因此.Where(r =&gt; r.Code == statusCode).FirstOrDefault() 可以只是.FirstOrDefault(r =&gt; r.Code == statusCode)
  • 您不能使用 Moq 模拟 Where/FirstOrDefault,因为它们是 extension methods
  • 就我个人而言,我不会mock linq 查询,而是只会mock 业务逻辑,也就是包含linq 查询的方法;或模拟数据访问层并使其返回一组数据,因此您的真正 linq 查询仍将执行,只是针对模拟数据
  • 如果GetSomeDateAsync 返回List&lt;Domain.Student.Entities.SectionRegistrationStatusItem&gt; 那么它是如何异步的呢?它不应该返回Task吗?

标签: c# linq unit-testing mocking moq


【解决方案1】:

正如 cmets 中提到的,您不能模拟 Where 和/或 FirstOrDefault。您将模拟 _someDataRepository.GetSomeDataAsync(false) 并让 Where 处理从 GetSomeDataAsync 返回的数据。

很遗憾我没有测试过这段代码,但它可能会给你一些启发:

_someDataRepositoryMock.Setup(s => s.GetSomeDataAsync(It.IsAny<bool>()))
                       .Returns(Task.FromResult(Your data here, i.e. List<Domain.Student.Entities.SectionRegistrationStatusItem>));

或者,如果您使用的是 Moq 4.2 或更高版本

_someDataRepositoryMock.Setup(s => s.GetSomeDataAsync(It.IsAny<bool>()))
                       .ReturnAsync(Your data here, i.e.  List<Domain.Student.Entities.SectionRegistrationStatusItem>);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 2019-10-02
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    相关资源
    最近更新 更多