tdd – 什么时候预期和什么时候存根?

我使用NMock2,并且我已经编写了以下NMock类来表示一些常见的模拟框架概念:

> Expect:这指定了一个嘲笑的方法应该返回的,并表示调用必须发生或测试失败(伴随着调用VerifyAllExpectationsHaveBeenMet()).
> Stub:这指定一个嘲笑的方法应该返回,但不能导致测试失败.

那么我该怎么办?

许多嘲弄的框架正在带来嘲笑和嘲笑的概念.短桩更近更靠近在一起,他们可以被认为在功能上几乎相同.但从概念上讲,我通常会遵循这个惯例:

> Mock:只有当你明确地试图验证被测对象的行为(即你的测试是说这个对象必须调用该对象).
>存根:当你试图测试一些功能/行为,但是为了得到这个工作,你需要依赖一些外部对象(即你的测试是说这个对象必须做某些事情,但作为副作用,它可能调用该对象)

当您确保每个单元测试仅测试一件事情时,这将变得更加清晰.当然,如果您尝试在一个测试中测试所有内容,那么您也可以预期所有内容.但是,只要预期特定单元测试正在检查的内容,您的代码就会更清楚,因为您可以一目了然地看到测试的目的是什么.

这样做的另一个好处是,你将会更容易地与变化和当更改导致中断时,获取更好的错误消息.换句话说,如果你微妙地改变了你的实现的一部分,你更有可能只得到一个测试用例的破坏,这将显示出什么是坏的,而不是一整套的测试破坏&只是创造噪音.

编辑:它可能会更清晰的基于一个有计划的例子,一个计算器对象审计数据库的所有添加(伪代码)…

public void CalculateShouldAddTwoNumbersCorrectly() {
    var auditDB = //Get mock object of Audit DB
    //Stub out the audit functionality...
    var calculator = new Calculator(auditDB);
    int result = calculator.Add(1,2);
    //assert that result is 3
}

public void CalculateShouldAuditAddsToTheDatabase() {
    var auditDB = //Get mock object of Audit DB
    //Expect the audit functionality...
    var calculator = new Calculator(auditDB);
    int result = calculator.Add(1,2);
    //verify that the audit was performed.
}

所以在第一个测试用例中,我们测试了Add方法功能.不关心审计事件是否发生,但是我们碰巧知道计算器将无法使用auditDB引用,所以我们只是将其存储起来,以给我们最少的功能来使我们的具体测试用例工作.在第二个测试中,我们专门测试当您执行添加时,会发生审计事件,所以在这里我们使用期望(注意,我们甚至不关心结果是什么,因为这不是我们正在测试的).

是的,你可以把这两种情况合并成一个,&做出预期并声称你的结果是3,但是你在一个单元测试中测试两个例子.这将使您的测试更脆弱(因为有更大的表面积可能会改变以破坏测试),而不太清楚(因为合并测试失败后,它不会立即显现出什么问题.还是审计不工作?)

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...