Принудительный повторный запрос элемента для запуска обработчика щелчков

#react-testing-library

#react-testing-library

Вопрос:

У меня есть тест, в котором я утверждаю, что мой запрос API предоставляет правильные параметры. Я использую MSW для макетирования api и предоставляю шпион для обработчика запросов:

 test("supplies order direction descending if header button is clicked twice", async () => {
    const mockHandler = jest.fn(handler);

    server.use(rest.get(`${config.apiHost}/targets`, mockHandler));

    // First request to /targets happens on render
    render(<Route>{(props) => <TargetList history={props.history} />}</Route>);
    const button = await screen.findByRole("button", { name: "Port" });

    // Second request to /targets happens on button click
    userEvent.click(button);
    await waitFor(() => {
      expect(mockHandler).toHaveBeenCalledTimes(2);
    });
    
    // Third request to /targets SHOULD happen here but doesn't
    userEvent.click(button);
    await waitFor(() => {
      expect(mockHandler).toHaveBeenCalledTimes(3);
      const lastCall = mockHandler.mock.calls[2];
      const requestArg = lastCall[0];
      expect(requestArg.url.searchParams.get("orderby")).toBe("port");
      expect(requestArg.url.searchParams.get("direction")).toBe("descending");
    });
  });
  

Приведенный выше код не работает, так как запуск события щелчка во второй раз на кнопке, похоже, ничего не делает. Однако, если я запрошу кнопку, я смогу успешно запустить обработчик:

 test("supplies order direction descending if header button is clicked twice", async () => {
    ...
    const button = await screen.findByRole("button", { name: "Port" });

    // Second request to /targets happens on b utton click
    userEvent.click(button);
    await waitFor(() => {
      expect(mockHandler).toHaveBeenCalledTimes(2);
    });
    // Third request to /targets now works!
    const button2 = await screen.findByRole("button", { name: "Port" });
    userEvent.click(button2);
    await waitFor(() => {
      expect(mockHandler).toHaveBeenCalledTimes(3); // SUCCESS!
      ...
    });
  });
  

Почему я должен повторно запрашивать один и тот же элемент? Я что-то делаю неправильно?

Комментарии:

1. У меня нет полного исходного кода, но я бы предположил, что вы делаете что-то в своем обработчике событий click, что заставит react снова отображать, и в этом случае старый элемент больше не будет присутствовать в dom, и, следовательно, событие click не будет вызвано. Не могли бы вы предоставить образец codesandbox?

2. @dipen Я думаю, что вы абсолютно правы. Не стесняйтесь добавлять ответ.

Ответ №1:

У меня нет полного исходного кода, но я бы предположил, что вы делаете что-то в своем обработчике событий click, что заставит react снова отображать, и в этом случае старый элемент больше не будет присутствовать в DOM, и, следовательно, обработчик событий click не будет вызван.

P.S: Вы можете использовать перехваты жизненного цикла react, чтобы определить, был ли компонент повторно отображен.