在带有 Mockito 的 JUnit 中,如何等待异步方法完成?
In JUnit with Mockito, how can I wait for an asynchronous method to complete?
我正在针对一些代码编写集成测试,这些代码在数据库中更新不同的值时异步创建记录。我想在创建记录后检查系统状态,验证它是否按预期创建。因此测试需要等到记录被创建。
我可以使用 Mockito 为创建记录的函数创建一个间谍。 Mockito 甚至可以选择等待通过 Mockito.timeout
调用方法,如果超过一定时间没有调用方法则放弃:
// Use or create/wire in spy. In my case, this is set up with @SpyBean from spring-boot-test.
RecordCreationService recordCreationServiceSpy = ...;
testClass.update(someValue);
Mockito.verify(recordCreationServiceSpy, Mockito.timeout(10_000)).createRecord(ArgumentMatchers.any());
但是,这只是等待调用开始,而不是等待调用完成。因此,这进入了一个竞争条件,其中验证可以在所需的调用完成之前完成。
在使用 Mockito 在 JUnit 中进行验证之前,我如何才能干净简单地等待流程完成?
此功能并不直接存在于 Mockito 中,因为当前存在将此功能添加到 Mockito 的未决问题 (Mockito issue #1089)。
我目前使用的解决方案是为等待调用完成再返回的spied方法编写自定义答案。然后我之后正常验证结果。
@SpyBean
private RecordCreationService recordCreationServiceSpy;
@Test(timeout = 10_000)
public void recordShouldBeCreatedWhenDataIsUpdated() {
// Set up test here
updateValueAndWait(value);
assertEquals(1, recordRepository.findAll().size());
// Perform any additional verifications
}
private void updateValueAndWait(String value) {
CountDownLatch latch = new CountDownLatch(1);
Mockito.doAnswer(invocation -> {
Object result = invocation.callRealMethod();
latch.countDown();
return result;
}).when(recordCreationServiceSpy).insertRecord(any());
testClass.update(value);
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
我正在针对一些代码编写集成测试,这些代码在数据库中更新不同的值时异步创建记录。我想在创建记录后检查系统状态,验证它是否按预期创建。因此测试需要等到记录被创建。
我可以使用 Mockito 为创建记录的函数创建一个间谍。 Mockito 甚至可以选择等待通过 Mockito.timeout
调用方法,如果超过一定时间没有调用方法则放弃:
// Use or create/wire in spy. In my case, this is set up with @SpyBean from spring-boot-test.
RecordCreationService recordCreationServiceSpy = ...;
testClass.update(someValue);
Mockito.verify(recordCreationServiceSpy, Mockito.timeout(10_000)).createRecord(ArgumentMatchers.any());
但是,这只是等待调用开始,而不是等待调用完成。因此,这进入了一个竞争条件,其中验证可以在所需的调用完成之前完成。
在使用 Mockito 在 JUnit 中进行验证之前,我如何才能干净简单地等待流程完成?
此功能并不直接存在于 Mockito 中,因为当前存在将此功能添加到 Mockito 的未决问题 (Mockito issue #1089)。
我目前使用的解决方案是为等待调用完成再返回的spied方法编写自定义答案。然后我之后正常验证结果。
@SpyBean
private RecordCreationService recordCreationServiceSpy;
@Test(timeout = 10_000)
public void recordShouldBeCreatedWhenDataIsUpdated() {
// Set up test here
updateValueAndWait(value);
assertEquals(1, recordRepository.findAll().size());
// Perform any additional verifications
}
private void updateValueAndWait(String value) {
CountDownLatch latch = new CountDownLatch(1);
Mockito.doAnswer(invocation -> {
Object result = invocation.callRealMethod();
latch.countDown();
return result;
}).when(recordCreationServiceSpy).insertRecord(any());
testClass.update(value);
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}