如何解决“更新未包含在 act() 中"的问题?测试库反应中的警告? [英] How to solve the "update was not wrapped in act()" warning in testing-library-react?

查看:29
本文介绍了如何解决“更新未包含在 act() 中"的问题?测试库反应中的警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个会产生副作用的简单组件.我的测试通过了,但我收到警告 Warning: An update to Hello inside a test was not wrapped in act(...)..

我也不知道 waitForElement 是否是编写此测试的最佳方式.

我的组件

导出默认函数Hello() {const [posts, setPosts] = useState([]);useEffect(() => {const fetchData = async() =>{const response = await axios.get('https://jsonplaceholder.typicode.com/posts');setPosts(response.data);}取数据();}, []);返回 (<div><ul>{帖子.地图(发布 =><li key={post.id}>{post.title}</li>)}

)}

我的组件测试

从'react'导入React;从@testing-library/react"导入 {render, cleanup, act };从'axios'导入mockAxios;从 '.' 导入你好;afterEach(清理);it('正确呈现你好', async () => {mockAxios.get.mockResolvedValue({数据: [{ id: 1, title: 'post one' },{ id: 2, title: 'post 2' },],});const { asFragment } = await waitForElement(() => render());期望(asFragment()).toMatchSnapshot();});

解决方案

更新答案:

请参阅下面的@mikaelrs 评论.

<块引用>

不需要waitFor 或waitForElement.你可以只使用 findBy* 选择器,它返回一个可以等待的承诺.例如等待 findByTestId('list');


已弃用的答案:

使用 waitForElement 是正确的方法,来自文档:

<块引用>

等到模拟的 get 请求承诺解决并且组件调用 setState 并重新渲染.waitForElement 等待直到回调没有抛出错误

这是您案例的工作示例:

index.jsx:

import React, { useState, useEffect } from 'react';从 'axios' 导入 axios;导出默认函数 Hello() {const [posts, setPosts] = useState([]);useEffect(() => {const fetchData = async() =>{const response = await axios.get('https://jsonplaceholder.typicode.com/posts');setPosts(response.data);};取数据();}, []);返回 (<div><ul data-testid="list">{posts.map((post) => (<li key={post.id}>{post.title}</li>))}

);}

index.test.jsx:

从'react'导入React;从'@testing-library/react'导入{渲染,清理,waitForElement};从 'axios' 导入 axios;从 '.' 导入你好;jest.mock('axios');afterEach(清理);it('正确呈现你好', async () => {axios.get.mockResolvedValue({数据: [{ id: 1, title: 'post one' },{ id: 2, title: 'post 2' },],});const { getByTestId, asFragment } = render(<Hello/>);const listNode = await waitForElement(() => getByTestId('list'));期望(listNode.children).toHaveLength(2);期望(asFragment()).toMatchSnapshot();});

100% 覆盖率的单元测试结果:

 通过 stackoverflow/60115885/index.test.jsx✓ 正确地打招呼(49 毫秒)-----------|---------|---------|---------|---------|-----------------档案 |% stmts |% 分支 |% 函数 |% 行 |未覆盖的行#s-----------|---------|---------|---------|---------|-----------------所有文件 |100 |100 |100 |100 |index.jsx |100 |100 |100 |100 |-----------|---------|---------|---------|---------|-----------------测试套件:通过 1 个,共 1 个测试:1 次通过,共 1 次快照:通过 1 个,共 1 个时间:4.98s

index.test.jsx.snapshot:

//Jest 快照 v1出口[`正确呈现你好1`] = `<文档片段><div><ul数据测试ID =列表"><li>贴一贴<li>贴二

</DocumentFragment>`;

源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60115885

I'm working with a simple component that does a side effect. My test passes, but I'm getting the warning Warning: An update to Hello inside a test was not wrapped in act(...)..

I'm also don't know if waitForElement is the best way to write this test.

My component

export default function Hello() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
      setPosts(response.data);
    }

    fetchData();
  }, []);

  return (
    <div>
      <ul>
        {
          posts.map(
            post => <li key={post.id}>{post.title}</li>
          )
        }
      </ul>
    </div>
  )
}

My component test

import React from 'react';
import {render, cleanup, act } from '@testing-library/react';
import mockAxios from 'axios';
import Hello from '.';

afterEach(cleanup);

it('renders hello correctly', async () => {
  mockAxios.get.mockResolvedValue({
    data: [
        { id: 1, title: 'post one' },
        { id: 2, title: 'post two' },
      ],
  });

  const { asFragment } = await waitForElement(() => render(<Hello />));

  expect(asFragment()).toMatchSnapshot();
});

解决方案

Updated answer:

Please refer to @mikaelrs comment below.

No need for the waitFor or waitForElement. You can just use findBy* selectors which return a promise that can be awaited. e.g await findByTestId('list');


Deprecated answer:

Use waitForElement is a correct way, from the docs:

Wait until the mocked get request promise resolves and the component calls setState and re-renders. waitForElement waits until the callback doesn't throw an error

Here is the working example for your case:

index.jsx:

import React, { useState, useEffect } from 'react';
import axios from 'axios';

export default function Hello() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
      setPosts(response.data);
    };

    fetchData();
  }, []);

  return (
    <div>
      <ul data-testid="list">
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

index.test.jsx:

import React from 'react';
import { render, cleanup, waitForElement } from '@testing-library/react';
import axios from 'axios';
import Hello from '.';

jest.mock('axios');

afterEach(cleanup);

it('renders hello correctly', async () => {
  axios.get.mockResolvedValue({
    data: [
      { id: 1, title: 'post one' },
      { id: 2, title: 'post two' },
    ],
  });
  const { getByTestId, asFragment } = render(<Hello />);

  const listNode = await waitForElement(() => getByTestId('list'));
  expect(listNode.children).toHaveLength(2);
  expect(asFragment()).toMatchSnapshot();
});

Unit test results with 100% coverage:

 PASS  stackoverflow/60115885/index.test.jsx
  ✓ renders hello correctly (49ms)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |      100 |     100 |     100 |                   
 index.jsx |     100 |      100 |     100 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        4.98s

index.test.jsx.snapshot:

// Jest Snapshot v1

exports[`renders hello correctly 1`] = `
<DocumentFragment>
  <div>
    <ul
      data-testid="list"
    >
      <li>
        post one
      </li>
      <li>
        post two
      </li>
    </ul>
  </div>
</DocumentFragment>
`;

source code: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60115885

这篇关于如何解决“更新未包含在 act() 中"的问题?测试库反应中的警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆