Изменения во время 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()это ключ.

Другие вопросы по тегам