Изменения во время UI.access() не передаются во время модульного теста.
У меня есть следующий класс представления:
@Route(value = NewsAdminView.ROUTE)
@RequiredArgsConstructor
public class NewsAdminView extends VerticalLayout {
public static final String ROUTE = "";
private final NewsService service;
final Grid<News> grid = new Grid<>(News.class);
@Override
protected void onAttach(AttachEvent attachEvent) {
addComponents();
service.getNews().subscribe(items -> updateItems(attachEvent.getUI(), items));
}
private void updateItems(final UI ui, final List<News> news) {
ui.access(() -> {
grid.setItems(news);
grid.setEnabled(true);
});
}
// Some details are omitted, like setting up the components and handling security, locale & URL parameters
}
Служба выполняет запрос GraphQL, который возвращает Mono<List>, который добавляет записи новостей на страницу после завершения. AppShellConfigurator имеет необходимую аннотацию @Push, и вся эта установка работает после развертывания и тестирования в браузере.
Но у меня также есть модульный тест, расширяющий модульные тесты Vaadin TestBench:
class NewsAdminViewTest extends VaadinUnitTest { // VaadinUnitTest extends Vaadin's SpringUIUnitTest
@MockBean
private NewsService service;
@BeforeEach
void setUp() {
news = News.builder().build();
when(service.getNews()).thenReturn(Mono.just(List.of(news)));
}
@Test
void openWithNoParameters() {
final NewsAdminView view = navigate(NewsAdminView.ROUTE, NewsAdminView.class);
assertThat(view.grid.isVisible()).isTrue();
assertThat(view.grid.isEnabled()).isTrue();
assertThat(view.grid.getDataProvider().size(new Query<>())).isEqualTo(1);
}
При отладке я вижу, что мойupdateItems()
вызывается метод, имитируемая служба возвращает имитируемый список записей новостей, элементы устанавливаются и сетка включена. Но шаг однаждыaccess()
вызов завершается, и изменения должны быть переданы клиенту, пропускается.VaadinSession.unlock()
называется, ноVaadinSession.getUIs()
пусто. И утверждения оenabled
состояние и количество отображаемых строк сетки не соответствуют действительности.
Это что-то, что модульные тесты еще не поддерживают, или мне что-то не хватает в моем приложении или настройке тестирования?
1 ответ
причина этого в том, что метод тестирования удерживает блокировку пользовательского интерфейса. Блокировка пользовательского интерфейса снимается только после завершения функции тестирования, что, по сути, откладывает всеui.access()
вызывает после завершения тестовой функции, а к тому времени уже слишком поздно.
Решение состоит в том, чтобы временно снять блокировку пользовательского интерфейса в тестовой функции, а затем вернуть ее обратно. Вы можете сделать это самостоятельно, вызвав соответствующие функции Vaadin, но есть способ получше. Тестирование пользовательского интерфейса Vaadin основано на Karibu-Testing, и вы также можете вызывать функции Karibu.
Дополнительную информацию см. в асинхронной документации Karibu-Testing ;тотMockVaadin.clientRoundtrip()
это ключ.