如何使用玩笑和酶正确测试反应功能组件?

How to test react functional component correctly using jest and enzyme?

我的-component.js

import axios from "axios";
import React from "react";

const UnitTest = () => {
  const [todo, set_todo] = React.useState({});

  React.useState(() => {
    const onMounted = async () => {
      const getTodo = await axios.get("https://jsonplaceholder.typicode.com/todos/1");
      set_todo(getTodo.data);
    };
    onMounted();
  }, []);

  return (
    <div id="UnitTest">
      <p>{todo.title}</p>
    </div>
  );
};

export default UnitTest;

api 响应

{
    "userId": 1,
    "id": 1,
    "title": "delectus aut autem",
    "completed": false
}

我的-component.test.js

import { mount } from "enzyme";

import UnitTest from "../../src/pages/unit-test";

describe("UnitTest component", () => {
  let wrapper = mount(<UnitTest />);

  it("should render the component", () => {
    wrapper = mount(<UnitTest />);
    console.log(wrapper.debug());
    expect(wrapper.find("p").text()).toEqual("delectus aut autem");
  });
});

测试结果

当 console.log(wrapper.debug()) 时如何让我的 <p> 标签包含 delectus aut autem 并且我是否可以更新状态 (set_todo) 成为

{
    "userId": 2,
    "id": 3,
    "title": "second title",
    "completed": true
}

从我的测试文件中更新断言成为 expect(wrapper.find("p").text()).toEqual("second titile"); ?

使用 jest.spyOn(object, methodName) 方法为 axios.get() 方法及其解析值创建模拟。

使用 act()promisesetTimeout 创建宏任务以等待 axios.get() 创建的方法的承诺在 useEffect 挂钩中解析。

例如

MyComponent.jsx:

import axios from 'axios';
import React from 'react';

const UnitTest = () => {
  const [todo, set_todo] = React.useState({});

  React.useEffect(() => {
    const onMounted = async () => {
      const getTodo = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
      set_todo(getTodo.data);
    };
    onMounted();
  }, []);

  return (
    <div id="UnitTest">
      <p>{todo.title}</p>
    </div>
  );
};

export default UnitTest;

MyComponent.test.jsx:

import UnitTest from './MyComponent';
import axios from 'axios';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';

const whenStable = async () => {
  await act(async () => {
    await new Promise((resolve) => setTimeout(resolve, 0));
  });
};

describe('67885144', () => {
  it('should pass', async () => {
    const axiosGetSpy = jest.spyOn(axios, 'get').mockResolvedValueOnce({ data: { title: 'delectus aut autem' } });
    const wrapper = mount(<UnitTest />);
    await whenStable();

    expect(wrapper.find('p').text()).toEqual('delectus aut autem');
    expect(axiosGetSpy).toBeCalledWith('https://jsonplaceholder.typicode.com/todos/1');
    axiosGetSpy.mockRestore();
  });
});

测试结果:

 PASS  examples/67885144/MyComponent.test.jsx (7.902 s)
  67885144
    ✓ should pass (45 ms)

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