在我看来,模拟正在测试实现。
具体来说,他们测试了实现与特定对象交互的方式。
100% 正确。但是,这仍然是单元测试,只是从不同的角度来看。
假设您有一个方法应该使用某种MathsService 对两个数字执行函数。 MathsService 被分配给 Calculator 类,以便为计算器进行数学运算。
让我们假设 MathsService 有一个方法,PerformFunction(int x, int y) 应该只是 return x+y。
像这样测试:(以下都是伪代码,为清楚起见,省略了某些位)
var svc = new MathsService();
var sut = new Calculator(svc);
int expected = 3;
int actual = sut.Calculate(1,2);
Assert.AreEqual(expected,actual,"Doh!");
这是对单元Calculator.Calculate() 的黑盒测试。您的测试不知道也不关心答案是如何得出的。这很重要,因为它可以让您对自己的测试正常进行有一定程度的信心。
但是,请考虑 Calculator.Calculate 的这种实现:
public int Calculate()
{
return 4;
}
像这样测试:
var svc = new Mock<IMathsService>(); //did I mention there was an interface? There's an interface...
svc.Setup(s=>PerformCalculation(1,2)).Returns(3);
var sut new Calculator(svc.Object);
sut.Calculate(1,2);
svc.Verify(s=>PerformCalculation(1,2),Times.Once,"Calculate() didn't invoke PerformFunction");
这个白盒测试并没有告诉您任何关于PerformFunction方法的正确性,但它确实证明了,不管结果如何,Calculator 确实将 x 和 y 传递给了 IAdditionService.PerformCalculation 方法,这就是您希望它执行的操作。
你当然可以编写其他测试来验证PerformCalculation测试的结果是否在不修改的情况下传回给调用者等。
有了这些知识,如果你的第一个单元测试现在失败了,你可以满怀信心地直接跳到 MathService 类来查找问题,因为你知道问题可能不是 @987654336 @方法。
希望对您有所帮助...