假设我使用方法x()
,y()
和z()
创建了MyClass类。假设x()
调用y()
,y()
调用z()
。
因此,每当我测试x()
时,y()
和z()
都会被调用。在模拟MyClass的依赖关系的情况下,我将不得不模拟x()
,y()
和z()
中的依赖行为。
因此,如果我对方法x()
的测试是testXWhen1()
,testXWhen2()
和testXWhen3()
,我将不得不重复对每个测试方法中的依赖关系的期望。最后,我有一些代码对我在三种测试方法中重复y()
和z()
内部的情况有所期望。有什么办法可以避免这种情况吗?
我的一个想法是尝试测试实际的x()
方法,但模仿y()
和z()
。在这种情况下,MyClass
的实例应该部分是模拟,部分是真实MyClass
。有可能吗?
另一种解决方案是严格遵守x()
中的期望,但不关注y()
和z()
中发生的事情......我想我可以@NonStrict
做到这一点而不是@Mocked
,但这不是我最喜欢的解决方案。
答案 0 :(得分:2)
如果您想测试方法x()
,那么您应该模拟方法y()
。在这种情况下,也不需要模拟z()
,因为您永远无法调用{{1}在z()
内部(y被模拟)。在不同的测试中测试你的x,y和z方法。使用PowerMock.It有y()
方法。
答案 1 :(得分:0)
最后,我有一些代码,对于我的三种测试方法重复y()和z()内部发生的事情的期望。有什么办法可以避免这种情况吗?
您是否尝试过“提取方法”重构?
另一个解决方案是严格关注x()中的期望,但不关注y()和z()中发生的事情......
这正是我在测试特定功能时所做的事情(虽然使用JMock) - 如果我正在测试的行为不依赖于对依赖性的调用的结果,我将明确使用JMock忽略/允许期望。它使测试的目的更加清晰,并专注于正在测试的内容。
答案 2 :(得分:0)
您可以使用JMockit的动态部分模拟功能,方法是将类或对象传递给Expectations/NonStrictExpectations
构造函数中的部分模拟。
一般而言,最好避免使用部分模拟,因为它通常表示测试代码缺乏凝聚力,导致难以理解的测试。
对于在多个测试中需要大量相同期望的情况,始终可以选择创建可重用期望块。您可以在命名的“XyzExpectations
”子类中封装许多期望,可选地使用参数化构造函数,并在任意数量的测试中实例化它(实际实例化的“期望”子类必须是final
)。验证块也可以这样做。