我正在使用 mockito 来模拟一个返回 Object[] 列表的 JpaRepository 类。嘲讽如下:
@MockBean
private UtilisateurSuiviRepository utilisateurSuiviRepository;
所以我正在使用这个模拟对象来测试不同的场景并返回不同的结果。
在第一个测试方法中我有这个:
when(utilisateurSuiviRepository
.findUtilisateursInactifsPourPremiereRelance(10))
.thenReturn(new ArrayList<Object[]>(){{
add(new Object[]{8L, Instant.now()});
}});
在第二种测试方法中,我有同样的东西,但参数和返回结果不同:
when(utilisateurSuiviRepository
.findUtilisateursInactifsPourPremiereRelance(16))
.thenReturn(new ArrayList<Object[]>(){{
add(new Object[]{5L,null});
}});
问题是,根据方法的执行顺序,我的第二个方法还记得第一个 mock 的返回结果,所以它返回两个列表:
new Object[]{8L, Instant.now() // <-- first list of array object
new Object[]{5L,null} //<-- second list of array object
期待的结果是:
new Object[]{5L,null} //<-- what should I get in the second method
我知道 mockito 为所有模拟保持相同的状态,所以我这样做是为了在每个测试方法之前初始化模拟:
@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
}
但这并没有改变任何东西,我一直遇到同样的问题。
请注意,我正在使用 SpringRunner 在 spring batch 的上下文中运行我的测试类:
@RunWith(SpringRunner.class)
@MyCustomBatchUnitTest
@TestPropertySource(properties = {"spring.batch.job.names=myJob"})
MyCustomBatchUnitTest的定义如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@SpringBootTest(classes = { CommonsConfiguration.class })
@AutoConfigureMockMvc
@ActiveProfiles({CommonsConfiguration.PROFILE_BATCH, CommonsConfiguration.PROFILE_TEST, CommonsConfiguration.PROFILE_BATCHTEST})
public @interface MyCustomBatchUnitTest{
}
我也尝试手动初始化模拟在每个方法中如下:
utilisateurSuiviRepository = mock(UtilisateurSuiviRepository.class);
when(utilisateurSuiviRepository
.findUtilisateursInactifsPourPremiereRelance(16))
.thenReturn(new ArrayList<Object[]>(){{
add(new Object[]{8L, Instant.now()});}});
但在那种情况下,紧随其后的模拟方法不会被处理。
下面是一个产生同样问题的 github 链接: https://github.com/MrPenguina/mockito_issue/blob/main/JobTest.java
正如评论中的人所解释的,我不得不使用:
Mockito.reset(utilisateurSuiviRepository);
因为
MockitoAnnotations.initMocks
方法在Mockito框架的@Mock
内使用,而不用于spring框架的@MockBean
。
还要注意,在 Spring Batch 的上下文中,我在声明中初始化了一个最终的
List
,该列表用于通过调用 JpaRepository
中的方法 addAll
来保存我的 beforeStep
的结果方法,这在我的案例中引起了问题,并不断给我一个累积结果:
private final List<Object[]> listeUtilisateurSuiviInactif = new ArrayList<>();
我不得不将此列表的初始化移动到读者的
beforeStep()
中,这样每次调用测试方法时都会初始化列表。
总之,我不得不纠正上面的错误,在
Mockito.reset
方法中使用@Before
方法。