我有一个控制器,它又调用一个用@Async
注释的服务方法。我想为控制器编写联合测试,以验证它在调用Service层的异步方法后立即返回。通常当我稍后测试一个特定的时候我会嘲笑下面的图层。这意味着在这种情况下,我有一个模拟的服务层,@Async
注释将无效。
@RestController
public class MyController {
// constructors and some fields
public ResponseEntity myControllerMethod() {
myService.asyncMethod(1);
return ResponseEntity.ok().build();
}
}
@Service
public class MyService {
// .. some fluff
@Async
public void asyncMethod(int bla) {
// doing some work
}
}
然后我得到了控制器的单元测试。
@Mock private MyService myService;
@Test
public void test() {
doAnswer(invocation -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
fail();
}
return null;
}).when(myService).asyncMethod(1);
long before = System.currentTimeMillis();
ResponseEntity r = myController.myControllerMethod();
long after = System.currentTimeMillis();
Thread.sleep(1000); // sleep to let executor service start
assertEquals(200, r.getStatusCodeValue());
verify(myService, times(1)).asyncMethod(1);
assertTrue(after - before < 500); // verify time took for the controller to respond is significantly less than the wait time of asyncMethod
}
我的测试在最后一个断言上失败,因为asyncMethod
没有异步运行,因为myService
是一个Mocked对象。有没有办法保留Mockito对象上的@Async
行为?或者是否有更好的方法来测试此代码,而不是使用Mockito?