reactjs 如何正确编写避免act()警告的Jest测试?

ioekq8ef  于 2023-11-18  发布在  React
关注(0)|答案(3)|浏览(154)

useEffect通常使用Promises来更新状态。
此更新导致jest中的长警告:Warning: An update to null inside a test was not wrapped in act(...).
如何正确编写Jest测试?
活的例子,可复制的例子:
https://codesandbox.io/s/jest-test-for-useeffect-with-promises-spieq?file=/index.test.js
index.test.js

import React from "react";
import Hello from "./Hello";
import { create, act } from "react-test-renderer";

it("works", () => {
  let root;
  act(() => {
    root = create(<Hello />);
  });

  // console.log("From test:", );
  let repr = JSON.stringify(root.toJSON());
  expect(repr).toBe('{"type":"span","props":{},"children":["Hello! "]}');
});

字符串
Hello.js

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

export default () => {
  const [count, setCount] = useState();

  useEffect(() => {
    Promise.resolve({}).then(() => setCount(4));
  }, []);

  return <span>Hello! {count}</span>;
};


的数据
更新1:
对于propasal中的一个也是相同的结果:


2fjabf4q

2fjabf4q1#

我建议你使用testing-library/react,它可以与jest一起顺利使用,并提供了jest的方法。
你的测试会变成这样:

import React from "react";
import Hello from "./Hello";
import { render } from '@testing-library/react';

it("works", () => {
   const { baseElement } = render(<Hello />);
   expect(baseElement).toBeTruthy();
});

字符串

编辑:为了完整起见,在您的示例中,您尝试测试组件中的更新是否发生在使用promise的效果之后。

为了 waitFor 某些东西,你可以使用方法findBy(findBy方法是getBy查询和waitFor的组合。

import React from "react";
import Hello from "./Hello";
import { render, findByText } from "@testing-library/react";
import "@testing-library/jest-dom";

it("works", async () => {
  const { baseElement } = render(<Hello />);
  expect(await findByText(baseElement, "Hello! 4")).toBeVisible();
});


让我解释一下,import "@testing-library/jest-dom"允许你使用方法toBeVisible
所以,这个测试正在渲染一个组件Hello,然后它在baseElement(组件本身)中等待(默认值为1000 ms),寻找文本“Hello!4”,如果找到,它将返回找到的元素,我们将测试它是否可见。

ijxebb2r

ijxebb2r2#

看起来这个样本工作正常

import React from "react";
import Hello from "./Hello";
import { render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";

it("works", () => {
  render(<Hello />);
  return waitFor(() => screen.getByText("Hello! 4"));
  // expect(baseElement.toBeTruthy();
});

字符串

mklgxw1f

mklgxw1f3#

使用react-test-renderer,我得到了同样的问题,并修复了它如下:

import 'react-native';
import React from 'react';
import App from '../App';

// Note: import explicitly to use the types shiped with jest.
import {it} from '@jest/globals';

// Note: test renderer must be required after react-native.
import renderer, { act } from 'react-test-renderer';

it('renders correctly', async () => {
  await act( () => {
   renderer.create(<App />);
  });
});

字符串
从本质上讲,它是自动生成的App.test.tsx文件及其原始内容,但我添加了
1.按照错误消息的建议,使用act(),并
1.等待

相关问题