单元模拟测试中的 It.IsAny 是什么以及 It.Is 是什么

问题描述 投票:0回答:2

对此已经提出了很多问题,但我认为我需要一些更基本的东西来澄清这个概念,因为我是 TDD 的初学者。到那时我就无法前进了。

请您看一下下面的测试方法,如果我理解有误,请解释一下:

[Test]
public void ShouldSearch()
{
         var ColumnList = new List<Column>();
    

下面的行意味着我正在嘲笑对象。

但这

It.IsAny<>()
在这里意味着什么?

 this.ColumnServiceMock.Setup(x => x.GetColumn(It.IsAny<Context>(), It.IsAny<Column>()))
                       .Returns(ColumnList);

 var result = this.getColouminfo.GetFinalRecords(this.context, this.gridColumn);

 this.ColumnServiceMock.Verify(x => x.GetColumn(It.Is<Context>(y => y == this.context),
 It.Is<Column>(y => y.Id == 2)), Times.Once);

  Assert.AreEqual(1, result.Data.Count, "Not equal");

  Assert.IsTrue(result.Data.Success, "No success");
c# unit-testing mocking tdd moq
2个回答
43
投票

It.IsAny<T>
正在检查参数是否是T类型,它可以是T类型的任何实例。它基本上是说,我不在乎你在这里传递什么,只要它是T类型即可。

this.ColumnServiceMock
    .Setup(x => x.GetColumn(It.IsAny<Context>(), It.IsAny<Column>()))
    .Returns(ColumnList);

上面的意思是,无论何时使用任何参数调用

GetColumn
方法(只要它们分别是
Context
Column
类型),都返回
ColumnList

It.Is<T>
允许您检查传入的内容并确定传入的参数是否满足您的需求。

this.ColumnServiceMock
    .Verify(
        x => x.GetColumn(It.Is<Context>(y => y == this.context), It.Is<Column>(y => y.Id == 2)),
        Times.Once);

上面断言

GetColumn
方法仅被调用一次,且
Context
参数等于
this.Context
Column
参数的 Id 属性等于 2。

编辑:几年后用更多的知识重新审视这个答案。

this.ColumnServiceMock
    .Verify(
        x => x.GetColumn(It.Is<Context>(y => y == this.context), It.Is<Column>(y => y.Id == 2)),
        Times.Once);

可以缩短为

this.ColumnServiceMock
    .Verify(
        x => x.GetColumn(this.context, It.Is<Column>(y => y.Id == 2)),
        Times.Once);

不需要使用It.Is来检查引用相等性,直接传递对象即可。


20
投票

It.IsAny<T>()
指定该类型的任何内容。

It.Is<T>()
更具体,需要 lamda 来确保它完全匹配。

两者都只是指定您不想在模拟时准确指定的参数的方法。因此,例如,如果参数是字符串名称,并且您不关心测试中的确切名称,则可以使用:

It.IsAny<string>()
在您的模拟规范中,它将匹配任何字符串。

如果您总是希望名称以“S”开头,那么您可以这样做

It.Is<string>(x => x.StartsWith("S"))
只会匹配以 S 开头的字符串。

© www.soinside.com 2019 - 2024. All rights reserved.