【问题标题】:The right way to use MOQ setup and returns使用 MOQ 设置和退货的正确方法
【发布时间】:2021-08-15 03:01:59
【问题描述】:

我是 MOQ 新手,我对设置方法有点困惑。下面的示例显示了我需要测试的一种方法。被测方法返回两个日期的最新时间,因此我创建了两个 datetime 对象并将它们传递给我的函数。我感到困惑的部分是返回调用。这忽略了我的方法中的逻辑并返回我告诉它的内容。例如,如果我说返回(date2),那么无论逻辑如何,断言都会通过。我是不是做错了什么?

public virtual DateTime LatestTime(DateTime t1, DateTime t2)
{
   if (t1.CompareTo(t2) > 0)
      return t1;

    return t2;
}

[Test]
[Category("Catalogue service")]
public void TestLatestTimeReturnsCorrectResult()
{
    //Arrange
    DateTime date1 = new DateTime(2014, 07, 25, 13, 30, 01);
    DateTime date2 = new DateTime(2014, 07, 25, 13, 30, 00);

    MockCatalogueService.Setup(x => x.LatestTime(date1, date2)).Returns(date2);

    //Act
    DateTime retDate = MockCatalogueService.Object.LatestTime(date1, date2);

    //Assert
    Assert.That(retDate == date2);
}

【问题讨论】:

    标签: c# unit-testing mocking moq


    【解决方案1】:

    您以错误的方式使用起订量。它旨在替代您测试的类所依赖的一些实现。例如,您正在测试一些使用数据库存储库的类:

    public class MyService
    {
        private IMyDbRepository _repos;
        
        public MyService(IMyDbRepository dbRepos)
        {
            _repos = dbRepos;
        }
    
        public string[] GetClientNames()
        {
            return _repos.GetAllClients().Where(c=>!c.IsDisabled).OrderBy(c=>c.Name).ToArray();
        }
    }
    

    您需要测试GetClientNames() 方法。但是你不能直到你有IMyDbRepository 实例。仅仅为了测试排序和过滤客户端的方法,创建和填充数据库太复杂和错误。

    出路是使用Moq

    [Test]
    public void TestGetAllClientsDoesNotReturnDisabledUsers()
    {
        var dbReposMock = new Mock<IMyDbRepository>();
        dbReposMock.Setup(r=>r.GetAllClients()).Returns(
                          new []{ new Client { Name="AAA", IsDisabled=true },
                                  new Client { Name="BBB", IsDisabled=false } });
    
        var myTestingService = new MyService(dbReposMock.Object);//You pass here the autogenerated object which follows the described primitive behavior without requiring DB at all.
        var clientNames = myTestingService.GetClientNames();
        Assert.AreEqual(1, clientNames.Length);
        Assert.AreEqual("BBB", clientNames[0]);
    }
    

    所以Moq 允许您动态生成假类(非密封)或接口实现(在运行时),并使用它们将您的测试功能与其他一切分离。因此,如果数据库结构中出现错误,您只会看到少数数据库测试失败,并且可以很容易地识别出问题所在,而如果您没有将代码与 Moq 解耦,则所有层的 100 个不同测试都失败了.

    【讨论】:

    • 是的,我正在以这种方式使用 MOQ。因为该方法在我的服务 API 中,所以我试图错误地使用 MOQ。实际上我什至不需要最小起订量来进行测试,只需要 NUnit。感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 2018-05-02
    • 1970-01-01
    相关资源
    最近更新 更多