2009-01-06 90 views
8

我正在使用依赖注入为我的课程以外的代码提供模拟测试。我发现自己一遍又一遍地写了很多相同的代码,因为我需要模拟AuthProvider,ConfigurationManager等等,这些都在我想测试的方法中使用。该方法包含分支(if-then-else),因此我有多个测试来测试该方法的所有执行路径。我正在多次实例化每个模拟(每种测试方法都有一次),但是想知道这是否是错误的方法? 此外,我对嘲笑和预设响应显然主要是复制粘贴,因为对每个方法调用AuthProvider.Authenticate()这样的调用如何避免在单元测试中使用模拟代码时出现重复代码

在每种方法中,我设置了一个模拟存储库,并在每个方法的结尾我验证模拟库。我应该建立一些工厂来创造这些模拟,并设定他们的期望和回报价值,如果是这样的话?

为了实现mock我使用RhinoMocks。

回答

5

“多次实例化每个模拟”不是问题。对象是免费的。

只要确定你没有多次定义模拟类。课程价格昂贵。

另外,您在TestCase中有一个“setUp”方法,它允许您创建所有测试使用的灯具。是的,它为每个测试重建。不,这不是一个问题,除非它很痛苦地缓慢。

1

这是我拿..

我不会的情况下使用模拟......我会用一个工厂方法返回一个假的实现类和使用依赖注入来使用这个实现来代替。 。这样你就可以避免重复,并且可以再次重新使用这个实现......再次这个工厂实现需要被正确地重构,即不重复。行为..类似..做了一个在子系统中的方法,当我在SUT上执行一些操作时调用...并且稍后调用verify()来验证这种行为......还有一个好的关于Martin Folwer bliki的文章Mock Aren't Stubs

0

如EasyMock的记录和重放框架失败,如果您不设置模拟调用期望。但是像Mockito这样的框架只需记录所有的调用,并让你只验证那些重要的调用。所以你不必在所有测试中的所有方法上设置期望值。然后回到你在每个测试方法中实例化Mocks的问题,有比使用setUp()方法更好的方法。 Mockito提供了@Mock注释。所以你声明你的变量(如字段),如: @Mock存储库模拟

并且只需在setUp()中调用initMocks()。声明的所有模拟对象都可以在您的测试中自动使用,而无需明确创建Mocks。

+1

“如果您不对模拟调用设置期望值,则像EasyMock这样的记录和重放框架会失败。” =>这是不正确的。包括EasyMock在内的所有模拟工具都允许开发人员具有“非严格”的期望。在EasyMock中,通过使用“createNiceMock()”方法创建一个“很好”的模拟来实现。 – 2009-08-12 21:58:16

2

假设你使用的是NUnit,你可以为你的Mocks使用实例变量并在Setup/Teardown中重置它们。如果您看到重复的模式,那么请执行您对生产代码所做的操作:重构并提取帮助程序方法,以表达您尝试实现的内容(如果根本没有共同性,那么生产代码的设计存在问题)。

如果在安装过程中有重要的部门,考虑为您的生产班级编写多个测试类。

最后,想想你的生产类是否太忙,应该将某些行为提取出来给一个帮助对象。

倾听测试!

+0

非常感谢你提供了一个富有洞察力的答案。我想知道如何去编写生产类的多个测试类。我如何命名多个测试类? – Fadeproof 2009-05-29 10:30:20