我在componentDidMount
中有这样的代码:
async componentDidMount() {
window.scrollTo(0, 0);
try {
// check if user has auto
const { vehicles: auto } = await api.getVehicles();
const items = auto.filter((car) => car.active);
if (items.length) {
this.setActiveAuto(items);
} else {
const { name } = await api.getCurrentMoto();
this.setState({
name
});
}
} catch (err) {
console.log(err);
}
}
我想在getCurrentMoto()
中测试正确的状态更新,所以我写了这样的测试:
const motoResponse = {
name: 'Honda'
};
const autoResponse = {
vehicles: [],
};
jest.mock('../api/api.js');
describe('<Component /> Component render', () => {
let wrapper;
beforeEach(() => {
api.getVehicles.mockResolvedValueOnce(autoResponse);
api.getCurrentMoto.mockResolvedValueOnce(motoResponse);
wrapper = shallow(<Component />);
});
test('correct data passed from endpoint to state in componentDidMount', () => {
expect(wrapper.state().name).toBe('Honda');
});
});
但是我的测试失败了
Expected: "Honda"
Received: ""
被嘲笑的api.getCurrentMoto.mockResolvedValueOnce(motoResponse);
似乎没有调用,我无法理解如何解决该问题或更改测试以测试componentDidMount
中正确的状态更新
答案 0 :(得分:0)
这是解决方案:
index.tsx
:
import React, { Component } from 'react';
import { api } from './api';
class XComponent extends Component {
constructor(props) {
super(props);
this.state = {
name: ''
};
}
public async componentDidMount() {
console.log('componentDidMount');
window.scrollTo(0, 0);
try {
// check if user has auto
const { vehicles: auto } = await api.getVehicles();
const items = auto.filter(car => car.active);
if (items.length) {
this.setActiveAuto(items);
} else {
const { name } = await api.getCurrentMoto();
this.setState({
name
});
}
} catch (err) {
console.log(err);
}
}
public setActiveAuto(items) {
//
}
public render() {
return <div>58082922</div>;
}
}
export default XComponent;
api.ts
:
export const api = {
async getVehicles() {
return { vehicles: [{ active: true }] };
},
async getCurrentMoto() {
return { name: 'real name' };
}
};
index.spec.tsx
:
import React from 'react';
import XComponent from './';
import { api } from './api';
import { shallow } from 'enzyme';
jest.mock('./api.ts');
window.scrollTo = jest.fn();
const motoResponse = {
name: 'Honda'
};
const autoResponse = {
vehicles: []
};
describe('<Component /> Component render', () => {
let wrapper;
beforeEach(() => {
(api.getVehicles as any).mockResolvedValueOnce(autoResponse);
(api.getCurrentMoto as any).mockResolvedValueOnce(motoResponse);
wrapper = shallow(<XComponent />);
});
test('correct data passed from endpoint to state in componentDidMount', done => {
expect.assertions(5);
expect(wrapper.text()).toBe('58082922');
setImmediate(() => {
expect(api.getVehicles).toBeCalledTimes(1);
expect(api.getCurrentMoto).toBeCalledTimes(1);
expect(window.scrollTo).toBeCalledWith(0, 0);
expect(wrapper.state().name).toBe('Honda');
done();
});
});
});
带有覆盖率报告的单元测试结果:
PASS src/stackoverflow/58082922/index.spec.tsx
<Component /> Component render
✓ correct data passed from endpoint to state in componentDidMount (43ms)
console.log src/stackoverflow/58082922/index.tsx:4305
componentDidMount
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 81.48 | 80 | 50 | 82.61 | |
api.ts | 33.33 | 100 | 0 | 33.33 | 3,7 |
index.tsx | 87.5 | 80 | 66.67 | 90 | 21,30 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 6.908s, estimated 11s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58082922