Ниже приведена упрощенная схема моего приложения. В нем есть класс Foobar, который вызывает фасадный метод для получения данных. Фасад затем вызывает веб-сервис для получения данных, затем немного манипулирует данными и возвращает их Foobar.
Теперь, поскольку веб-сервис может занять некоторое время, вызов метода фасада должен быть асинхронным. Поэтому метод фасада не имеет возвращаемого значения, вместо него используется объект обратного вызова. Посмотрите на пример и продолжите чтение ниже.
public class Foobar {
private List<DTO> dtos;
@Autowired
private Facade facade;
public void refresh() {
facade.refreshFoobar(new CallBack() {
public void dataFetched(List<DTO> dtos) {
setDtos(dtos);
}
});
}
public void setDtos(List<DTO> dtos) {
this.dtos = dtos;
}
}
public class Facade {
...
public void refreshFoorbar(CallBack cb) {
// Fetch data from a web service
List<DTO> dtos = webService.getData();
// Manipulate DTOs
....
// call on the callback method
cb.dataFecthed(dtos);
}
}
У меня есть два способа сделать метод фасада асинхронным: либо создать поток вручную, либо использовать аннотацию @Async.
public class Facade {
public void refreshFoorbar(CallBack cb) {
new Thread() {
@Override
public void run() {
....
}
}.start();
}
}
// ... OR ...
public class Facade {
@Async
public void refreshFoorbar(CallBack cb) {
....
}
}
Моя проблема в том, что теперь мне нужно написать интеграционный тест для этой цепочки вызовов методов. Я думаю, что мне нужно заставить вызов async-фасада быть синхронным при выполнении интеграционного теста, иначе я не буду знать наверняка, когда я смогу сделать соответствующие утверждения. Единственная идея сделать вызов метода синхронным - это использовать потоки с ручной обработкой и сделать потоки условными (так, для целей тестирования у меня есть предложение if, которое определяет, должен ли метод фасада выполняться в отдельном потоке или нет).
Однако у меня есть ощущение, что можно найти лучшее решение моей проблемы, будь то лучший способ заставить метод работать синхронно, например, с помощью Spring, или каким-то образом протестировать многопоточность.
Вот здесь мне и нужны ваши предложения, как бы вы решили мою проблему? Обратите внимание, я использую junit как для модульных, так и для интеграционных тестов.