如何使用玩笑和酶正确测试反应功能组件?
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() 与 promise
和 setTimeout
创建宏任务以等待 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
我的-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() 与 promise
和 setTimeout
创建宏任务以等待 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