【问题标题】:Unit testing LINQ which returns an integer单元测试 LINQ 返回一个整数
【发布时间】:2016-05-02 09:49:49
【问题描述】:

我有这个测试来验证我是否在我的参考中调用了 Query()。

[TestFixture]
public class When_retrieving_an_application_license
{
    [Test]
    public void available_licenses_should_be_counted()
    {
        // Arrange
        var sut = new LicenseManager();
        var mockILicenseRepository = new Mock<ILicenseRepository>();
        sut.LicenseRepository = mockILicenseRepository.Object;
        // Act
        sut.GetLicenseCount(Guid.NewGuid(), Guid.NewGuid());
        // Assert
        mockIApplicationLicenseRepository.Verify(x => x.Query());
    }
}

但是,GetLicenseCount(Guid.NewGuid(), Guid.NewGuid()) 函数看起来像这样:

 public int GetLicenseCount(Guid cId, Guid appId) 
          => LicenseRepository.Query()
             .Count(al => al.CId == cId && al.AppId == appId 
                                        && al.UserId == null 
                                        && al.Expiry > DateTime.UtcNow);

Query() 在 repo 中返回 all 以计算哪些 UserId 为 null。 即使它只验证 linq 的 query() 部分,是否可以说测试是 OK 的? 计数呢?

【问题讨论】:

  • 我更喜欢为不同的目的使用不同的测试。所以如果你检查某个方法或属性是否被调用并检查返回值是否正确,这应该是两个测试。我将创建第二个测试,它断言返回值。
  • 我建议您根本不应该验证 Query 是否被调用。设置您的存根存储库查询以返回一些值并验证您的方法是否返回您对这些值所期望的结果。测试行为,而不是如何实现。
  • 我同意@CharlesMager。测试.Query() 只是浪费时间。认为它就像您的应用程序中的 SQL 查询。对业务需求中的领域和行为进行单元测试。

标签: c# unit-testing mocking nunit nunit-3.0


【解决方案1】:

如果您想确保返回正确的计数,您需要安排模拟的 ILicenseRepository 以返回您期望的数据。

var mockILicenseRepository = new Mock<ILicenseRepository>();
mockILicenseRepository.Setup(x => x.Query()).Returns(new {CId = guid, AppId = guid2, Expiry = DateTime.Now.AddDays(1)};

您还需要存储返回值以进行断言

var actualCount = sut.GetLicenseCount(Guid.NewGuid(), Guid.NewGuid());
Assert.AreEqual(expectedCount, actualCount);

但是,如果您正在对 LINQ 的 Query 方法进行单元测试,那么我认为您可能需要重新构建您的生产代码,因为单元测试框架方法是不必要的。

【讨论】:

  • 看起来您使用 Moq 作为您的模拟框架,所以我的示例使用该语法(我的断言是 MsTest,不确定您使用的是什么)。仅供参考
猜你喜欢
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 2021-04-02
相关资源
最近更新 更多