Unit Test 学习 -- 基础篇 TestDouble

来源:互联网 发布:淘宝网供货平台 编辑:程序博客网 时间:2024/06/05 19:55

近日接手一个Unit Test 编写的活,因为之前的开发过程中没有编写相应的Test Code, 在项目开发的后期需要完善之。

在此之前,我只做过很少一部分关于JUnit 的工作,而目前面对的代码量很大,需要深入测试,所以有必要从头开始认真学习一下Unit Test 了。在学习的过程中我找到一个有趣的概念 Test Double. (双测试???),再深入其中才发现自己是多么的幼稚:原来特技替身演员的英文说法是 'stunt double", 那么对应到这里的Test Double就是测试替身,什么测试还有替身,对,这里的替身就是用来代替那些被测试代码依赖的对象模拟。

Test Double is a generic term for any case where you replace a production object for testing purposes.[1] 测试替身是,在任何情况下,为了测试目的而替换掉相应产品对象的通用术语。

按照[1] 的内容,现有的测试替身有以下几种类型。

  • Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
  • Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (anInMemoryTestDatabase is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.
  • Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent.
  • Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting.
从[2]中我们找到对应的中文版,因为英文不太好,防止下一次看不太懂,所以就摘录在此
  • 虚拟(dummy)  最简单最原始的 test double 类型。虚拟不包含任何实现,且主要是在需要作为参数值时使用,而不作他用。空值可以认为是虚拟,但是真正的虚拟是接口或基类的派生,根本没有任何实现。
  • 存根(stub)  作为虚拟的进一步,存根是最低程度的接口或基类实现。返回 void 的方法通常根本不包含任何实现,而返回值的方法则通常会返回硬编码值。
  • 监视(spies) 测试监视与存根相似,但是除了向客户端提供可以调用其上成员的实例之外,监视还会记录已调用了哪些成员,以便单元测试验证是否按预期调用了成员。
  • 虚设(fake) 虚设包含更复杂的实现,通常处理它继承的类型的不同成员之间的交互。虚设虽然不是完整的产品实现,但是可能类似于产品实现,尽管它使用了一些快捷方式。
  • 模拟(mock) 模拟是由模拟库动态创建的(其他类型通常由测试开发人员使用代码创建)。测试开发人员从来不会看到实现接口或基类的实际代码,但是他们可以配置模拟来提供返回值,预见将会调用特定成员等等。根据配置的不同,模拟的行为可以类似于虚拟、存根或监视。
它们分别解决的问题的层次为[3]:
  • Dummy 为了能编译通过, 我需要依赖被满足
  • Stub 为了能正常运行, 我希望依赖的实现不要出错
  • Spies 为了能验证测试是否按照预期调用了成员。
  • Fake 为了覆盖到真实场景下的用例, 我需要依赖能够模拟真实场景下的行为, 并且我可以在不同的测试用例下指定不同的行为
  • Mock 在无法方便的观测系统状态变化而做出断言时, 我希望可以退而求其次, 能够得知SUT(System Under Test)正确的与外部依赖进行了交互. 

参考:

[1] http://martinfowler.com/bliki/TestDouble.html

[2]http://msdn.microsoft.com/zh-cn/magazine/cc163358.aspx

[3] http://blog.csdn.net/chelsea/article/details/7176479

[4]xUnit Test Patterns


 

0 0
原创粉丝点击