在单元测试中,我想检查是否调用了一个或另一个方法。由于Mockito,我可以轻松地验证一些方法被调用了多少次,但是verify
没有像“ OR”这样的验证模式。任何解决方法?
在我的情况下,我想检查SharedPreferences.Editor
上的名称是.apply()
还是.commit()
,因为这两种可能性使我满意并保存了数据。不幸的是,如果我致电verify(mEditor).apply()
,但由于即时保存的要求,有人将实施方式更改为.commit()
,则测试将失败,但不应这样做,因为我只想从这种角度进行测试,如果数据是否保存。这是单元测试,应该独立于此类更改,并且仅检查内部测试的范围。
答案 0 :(得分:1)
我不知道这样做的好方法,说实话,我认为真正的答案是:不。是的,另一个答案显示了一种实现您所要求的方法,但是然后:
您知道生产代码应该做什么。意思是:与其编写允许“ this or that”的 single 验证代码,不如编写两个独立的测试,一个用于“ this”,一个用于“ that” “。
换句话说,您可以控制测试内容。因此,编写一个应导致apply()
的测试,并编写一个应导致commit()
的测试。然后verify()
那个一个案例,预计每个测试都会看到该案例!
单元测试应该简单明了。当某件事失败时,您可以快速查看单元测试,并且您已经知道在生产代码中可以查找到根本原因的位置。任何会增加测试复杂性的事情都可能使之变得更加困难。最好有两个遵循清晰的“何时验证”路径的测试,而不是具有一个(或多个)“然后验证或验证”的测试。
答案 1 :(得分:1)
您要求的解决方法是捕获基础的MockitoAssertionError(或仅捕获AssertionError
):
try {
verify(mEditor).apply();
} catch (MockitoAssertionError mae) {
// apply was not called. Let's verify commit instead.
verify(mEditor).commit();
}
或者,如果apply
和commit
都调用某些(内部)save
方法,则您也可以尝试验证(假设它是公开的,基于模拟的测试可能会不一致)隐藏信息)。或者,如果您可以控制要测试的代码,则可以按照以下说明进行重构。
但是,更好的建议是,完全避免这种情况的发生,如answer by @GhostCat所述。