如何在Mockito上验证满足许多条件中的一个?是否可以验证是否调用了一个或另一个方法?



在我的单元测试中,我想检查是否调用了一个或另一个方法。借助 Mockito,我可以轻松验证某些方法被调用了多少次,但verify没有像"OR"这样的验证模式。有什么解决方法吗?

就我而言,我想检查SharedPreferences.Editor是否被称为.apply().commit(),因为其中两种可能性满足我并保存数据。不幸的是,如果我打电话给verify(mEditor).apply()但由于即时保存的要求,有人会将实现更改为.commit(),测试将失败,但不应该,因为我只想从这个角度测试数据是否保存。它是单元测试,应该独立于此类更改,并且只检查内部测试的范围。

您要求的工作是捕获底层的 MockitoAssertionError(或只是AssertionError):

try {
verify(mEditor).apply();
} catch (MockitoAssertionError mae) {
// apply was not called. Let's verify commit instead.
verify(mEditor).commit();
}

或者,如果applycommit都调用某种(内部)save方法,您也可以尝试验证(假设它是公开的 - 基于模拟的测试可能与信息隐藏不一致)。或者,如果您可以控制要测试的代码,则可以按照这些行重构它。

不过,更好的建议是完全避免这样做,正如@GhostCat在回答中所论证的那样。

我不知道有什么好方法可以做到这一点,老实说,我认为真正的答案是:不要那样做。是的,另一个答案显示了实现您要求的方法,但是:

您知道您的生产代码应该做什么。意思是:与其写一段允许"这个或那个"的验证码,不如写两个独立的测试,一个用于"这个">,一个用于"那个"。

换句话说:您可以控制测试的内容。所以写一个应该导致apply()的测试,和一个应该导致commit()的测试。然后verify()每个测试都应该看到的一个案例!

单元测试应该是直截了当的。当某些内容失败时,您可以快速查看单元测试,并且您已经知道在生产代码中查找何处以发现根本原因。任何增加测试复杂性的事情都可能使测试变得更加困难。最好有两个测试遵循明确的"何时验证"路径,而不是有一个(或多个)测试"何时验证此或验证"。

相关内容

  • 没有找到相关文章

最新更新