【问题标题】:Asyncronous test using React Testing Library/WaitFor使用 React 测试库/WaitFor 进行异步测试
【发布时间】:2021-08-16 17:57:53
【问题描述】:

我正在寻找使用流行的 React 测试库来解决这个问题的最简单的方法。我查看了很多链接,但似乎没有什么适合..

下面是最简单形式的组件:

import React, { useState, useEffect } from "react";

function App() {
    const [loggedIn, setLoggedIn] = useState(false)

    useEffect(() => {
        setTimeout(() => setLoggedIn(true), 1000)
      }, [])
      return (
      <button data-testid="login-button">{loggedIn ? "Log Out" : "Log In"}</button>
      );
}
export default App;

下面是按钮“无等待”状态的测试,但想知道如何在同一测试中实现“waitFor”,以测试 1 秒后按钮中文本的变化..

import { render, screen, waitFor } from "@testing-library/react";
import App from "./App";
test('Check the text "Log out" is eventually there', () => {
    render(<App />);
    const LoginButton = screen.getByText(/Log/)
    expect(LoginButton).toHaveTextContent(/Log In/i);
    /*How to use waitFor here*/
});

我知道我们可以轻松地模拟 API 调用的返回,对于这个问题,我们可能必须返回一个 Promise,然后才能使用“waitFor”进行测试。我们如何在上面的示例测试文件中使用“WaitFor”?

【问题讨论】:

    标签: javascript reactjs react-testing-library


    【解决方案1】:

    您可以使用 jest 的 Timer Mocks 来处理 setTimeouts。

    import { act, render, screen } from "@testing-library/react";
    import App from "./App";
    
    test("renders learn react link", () => {
      // use the fake timer
      jest.useFakeTimers();
      render(<App />);
    
      // assert the initial text of the button
      expect(screen.getByRole("button", { name: "Log In" })).toBeInTheDocument();
    
      // advance the timer
      act(() => jest.advanceTimersByTime(1000));
    
      // assert the changed text of the button
      expect(screen.getByRole("button", { name: "Log Out" })).toBeInTheDocument();
    
      // switch back to use real timers
      jest.useRealTimers();
    });
    

    参考:

    Using act() for timers

    【讨论】:

      【解决方案2】:

      感谢 Shyam 帮助我找到解决方案,这不是 在这种情况下使用测试库中的“waitFor”:

      test('Check the text "Log out" is finally there', () => {

      jest.useFakeTimers();

      渲染();

      //使用正则表达式定位引用元素

      const LoginButton = screen.getByText(/Log/);

      //实时搜索按钮上的初始/默认文本

      expect(LoginButton).toHaveTextContent(/Log In/i);

      //提前计时

      act(() => jest.advanceTimersByTime(1000));

      // 断言按钮的更改文本

      expect(LoginButton).toHaveTextContent(/Log Out/i);

      // 切换回使用实时计时器

      jest.useRealTimers();

      });

      【讨论】:

        猜你喜欢
        • 2021-04-19
        • 1970-01-01
        • 2021-06-08
        • 2021-06-14
        • 2020-07-19
        • 2021-07-17
        • 2019-12-31
        • 1970-01-01
        • 2013-06-28
        相关资源
        最近更新 更多