什么是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
方法(只要它们分别是 Context
和 Column
的类型),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来检查引用相等性,你可以直接传递对象。
关于这个已经有很多问题被问到,但我认为我需要一些更基本的东西来澄清这个概念,因为我是 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
方法(只要它们分别是 Context
和 Column
的类型),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来检查引用相等性,你可以直接传递对象。