我有一个相当复杂的方法,我想测试行为(使用Mockito和JUnit)。此方法将一个对象(我们称其类型为State
)作为输入,并应考虑几个不同的状态变量来决定其输出。调用mockito中的模拟对象
作为一个例子,考虑下面的说明书(s
是State
类的模拟):
- 如果
s.varOne
被设置,返回其值。 - 否则,如果设置了
s.varTwo
,则返回该值。 - 否则,如果
s.varThree
设置,调用s.update(s.varThree)
然后返回s.varOne
,现在将有一个值(即使它没有在阶段1) - 否则,抛出一个错误。
为了测试案例3得当,我想建立s
对象,以便s.varOne
和s.varTwo
都没有设置,开始用,但如果(且仅当!)的SUT调用s.update(s.varThree)
,再经过那s.varOne
返回的东西。
有没有一种很好的方法来在Mockito中设置这种行为?
我已经考虑为s.varOne
设置一些返回值链,然后验证调用的顺序是否与输出的顺序相对应(以及当然,sut的返回值是否正确) ,但这感觉很脏;如果我然后改变方法来计算其返回值的方式,它调用s.varOne
不同的次数,但不会改变它的输出,那么即使功能相同,测试也会失败。
我的理想解决方案是,我可以为模拟对象添加一些“延迟”设置,当该对象调用s.update()
方法时运行该对象,但我无法找到实现该方法的方法。
关于您的测试的可疑之处在于您的第三个示例中您的模拟成为测试中的系统。你可以让模拟返回任何你想要的,但你想测试**模拟**返回一定条件下的东西。难道你不能重组你的代码,以便你的SUT是一件事而不是1.x事情吗? –
这听起来像你在同一个测试用例中有多个断言一样。你能否把你的测试案例分解成更小的测试用例,每个测试用例只测试一个条件?你不应该在模拟中需要任何条件逻辑。如果您正在测试的代码将模拟调用两次,并且每次都要求不同的返回值,那么只需将多个值传递给您的'thenReturn'调用(如我的示例http://stackoverflow.com/questions/8088179/using -mockito与 - 多呼叫到所述-相同方法-用最同参数/ 8395685#8395685)。 –
@DavidWallace:如问题所述,我不想创建一个返回值链,因为这会使得测试依赖于实现而不仅仅依赖于合约(即“必须获得varOne'两次,然后调用'update()',然后重新获得它,否则测试将失败,即使合同 - 也许 - 仍然是全满的)。 –