以下是使用jestjs和react-dom/test-utils进行单元测试的解决方案:
index.tsx:
import React, { useState, useEffect } from 'react';
function sample(props) {
const { counter } = props;
const [displayIcon, setDisplayIcon] = useState(counter);
function isLocalstoragePresent() {
return localStorage.getItem('some_Id');
}
useEffect(() => {
if (isLocalstoragePresent()) {
setDisplayIcon(true);
} else {
setDisplayIcon(false);
}
}, [counter]);
return <div>{displayIcon ? 'icon' : ''}</div>;
}
export default sample;
index.test.tsx
:
import Sample from './';
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { act } from 'react-dom/test-utils';
describe('60639673', () => {
let container;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
unmountComponentAtNode(container);
container.remove();
container = null;
});
it('should display icon', async () => {
jest.spyOn(localStorage.__proto__, 'getItem').mockReturnValueOnce('1');
const mProps = { counter: false };
await act(async () => {
render(<Sample {...mProps}></Sample>, container);
});
expect(container.querySelector('div').textContent).toBe('icon');
expect(localStorage.__proto__.getItem).toBeCalledWith('some_Id');
localStorage.__proto__.getItem.mockRestore();
});
it('should not display icon', async () => {
jest.spyOn(localStorage.__proto__, 'getItem').mockReturnValueOnce('');
const mProps = { counter: true };
await act(async () => {
render(<Sample {...mProps}></Sample>, container);
});
expect(container.querySelector('div').textContent).toBe('');
expect(localStorage.__proto__.getItem).toBeCalledWith('some_Id');
localStorage.__proto__.getItem.mockRestore();
});
});
100%覆盖率的单元测试结果:
PASS stackoverflow/60639673/index.test.tsx (9.723s)
60639673
✓ should display icon (41ms)
✓ should not display icon (8ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.tsx | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 11.242s
依赖项版本:
"react": "^16.12.0",
"react-dom": "^16.12.0",
"jest": "^25.1.0"
源代码: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60639673
该链接提供了一个React和Apollo GraphQL的起始项目,其中包含示例代码和结构。
isLocalstoragePresent
移至函数外,并进行测试(如果您愿意的话)。然后运行一个浅层测试,其中模拟isLocalstoragePresent
的返回值分别为正和负。除非您使用 spy 和 mock useState,否则无法获取计数器的值,这需要更复杂的处理。 - Joe Lloydreturn localStorage.getItem("some_Id"); } 并编写了以下测试用例, it("检查是否调用了isLocalstoragePresent", () => { const isLocalstoragePresent = jest.fn(); expect(isLocalstoragePresent).toHaveBeenCalled(); }); 但仍然失败,我尝试使用mockImplementation而不是jest.fn(),但仍然出现了我提到的错误,请问我做错了什么?请给予建议。 - MK6