mockito 以随机顺序运行JUnit测试时出现UnfinishedStubbingException

yshpjwxd  于 2022-11-08  发布在  其他
关注(0)|答案(1)|浏览(241)

以下测试是我使用此Maven命令以随机顺序运行测试时失败的几个测试之一:*mvn -Dsurefire.runOrder=随机清洁测试 *

  1. @Test
  2. public void ShouldReturnCorrectAccountLoanSumForDebtRatioWhenRedemptionAmountIsNull(){
  3. AccountVO account = mock(AccountVO.class);
  4. CustomerGroupInformationVO group = mock(CustomerGroupInformationVO.class);
  5. when(group.getCustomerIds()).thenReturn(Set.of("199406208123"));
  6. when(account.getAccountOwners()).thenReturn(List.of((new AccountOwnerVO(null, "199406208123", null))));
  7. when(account.getAmount()).thenReturn(BigDecimal.valueOf(500000));
  8. when(account.getRedemptionAmount()).thenReturn(null);
  9. assertEquals(BigDecimal.valueOf(500000), getAdjustedAccountLoanSumForDebtRatio(account, group, caseClientVO));
  10. }

更具体地说,这是提到的行:

  1. when(account.getAccountOwners()).thenReturn(List.of((new AccountOwnerVO(null, "199406208123", null))));

你知道是什么原因造成的吗?我怎么修复它?当我用mvn干净安装正常运行我的测试时,没有任何问题。我希望它以随机顺序工作的原因是我们的构建工具似乎在使用它,它不能构建。就像我说的,它在本地工作得很好。

gj3fmq9x

gj3fmq9x1#

因为Mockito通过side-effects stored in ThreadLocal variables工作,所以它特别容易受到测试污染的影响:如果您的测试在以随机顺序运行时失败,可能是因为某些先前的测试使mock处于它不期望的状态。另外,Mockito存根依赖于以特定顺序观察方法调用,如果它不能观察方法调用(例如当它们是final时)或者如果您在准备thenVerb参数时与不同的mock交互,则可能导致奇怪的异常。
您的第一道防线之一是使用validateMockitoUsage,它应该在每次测试结束时运行,并确认没有与Mockito的交互未完成。您可以将其放在@After方法中,但如果使用MockitoJUnitRunnerMockitoRule,Mockito会自动执行此操作。如果可能,我建议使用后两种方法中的任何一种,尤其是MockitoRule。
这将帮助你确认哪些测试有问题。一旦你到了那里,尝试以下测试:

  • 再次确认您没有尝试在没有Mockito的选择性final支持的情况下模拟final方法。如果Mockito不能覆盖您的模拟方法,它将无法检测到您的存根调用。如果您的任何方法是用Kotlin编写的,请记住,与Java不同,除非声明为open,否则这些方法是final
  • 您的测试似乎没有使用Matchers,但是如果您使用了Matchers,请确保您对方法中的所有参数都使用了Matchers(如果您对方法中的任何参数都使用Matchers)。
  • 在stubbing过程中调用实方法时要小心。new AccountOwnerVO(...)不应该与mock交互,但如果它与mock交互,那么Mockito可能会将其解释为您的when调用从未得到thenReturn(实际上它只是还没有得到它)。将返回值提取为局部变量是一个合理的尝试步骤。

相关问题