什么是it.isAny,什么是单元模拟测试中的it.is

What is it.isAny and what is it.is in Unit mock testing

关于这个已经有很多问题被问到,但我认为我需要一些更基本的东西来澄清这个概念,因为我是 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");

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

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

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

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

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

It.Is<string>(x => x.StartsWith("S")) 只匹配以 S.

开头的字符串

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

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

上面说的是,只要使用任何参数调用 GetColumn 方法(只要它们分别是 ContextColumn 的类型),return 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来检查引用相等性,你可以直接传递对象。