Moq - 使用It.Is<>传递参数vs不使用它时

时间:2016-04-17 10:11:16

标签: c# unit-testing moq

在哪些情况下使用It.Is<>是至关重要的。将参数传递给Moq设置时的语法,而不是单独检索此参数的值,然后以“普通”方式传递它?到目前为止,我的测试需求可能有限,但我没有遇到需要使用它.Is<>哪个无法在mock.Setup之外定义? It.Is<>当我浏览消息来源时看起来非常受欢迎,也是为了这些基本的例子,所以我想知道什么是优势。下面是简洁的简单示例,但我遇到的其他情况也没有任何区别。我的意思是:

mockRepo.Setup(m =>m.GetAllReadingsOn
(latestDate)
.Returns(_filteredReadings);

VS

mockRepo.Setup(m => m.GetAllReadingsOn
(It.Is<DateTime>(d => d ==_latestDate)))
.Returns(_filteredReadings);

1 个答案:

答案 0 :(得分:3)

我会一直使用第一种方法,因为它更短。有一个例外:无法比较的引用类型,因为测试中的方法会创建它们。在这种情况下,您需要按属性比较属性以确保方法创建并传递正确的引用类型:

mockRepo.Setup(m => m.GetAllReadingsOn(It.Is<SomeComplexObject>(x => 
    x.Foo == "foo" && 
    x.Bar == "bar" && 
    x.Baz == 123)))
.Returns(_filteredReadings);

据说使用这种方法与DateTimes等值类型完全浪费了键击。

根据评论部分的要求,这是第一种方法不起作用的基本示例。假设我们要测试以下方法:

public SomeResult FooBarBaz()
{
    var myModel = new SomeComplexObject();
    myModel.Foo = "foo";
    myModel.Bar = "bar";
    myModel.Baz = 123;
    var result = repository.GetTheResult(myModel);

    return result;
}

现在很明显,如果你尝试编写下面的测试,它将会失败:

// arrange
var sut = new Sut();
var myModel = new SomeComplexObject();
myModel.Foo = "foo";
myModel.Bar = "bar";
myModel.Baz = 123;
var expected = new SomeResult();
mockRepo
    .Setup(m => m.GetAllReadingsOn(myModel)
    .Returns(expected);

// act
var actual = sut.FooBarBaz();

// assert
Assert.AreEqual(expected, actual);