[英]Stateful React component with async function failing Jest test
我正在这里关注Pluralsight的Jest测试教程 。 我编写的代码与作者完全一样,但出于某种原因我的测试没有通过。
我对作者回购的请求: https : //github.com/danielstern/isomorphic-react/pull/19
我有一个简单的React组件,它通过对componentDidMount
的服务的异步/等待调用来更新它的count
状态。
{this.state.count != -1 ? `${this.state.count} Notifications Awaiting` : 'Loading...'}
由于我已经模拟了NotificationsService,并将count设置为42
,因此测试应该在组件内传递"42 Notifications Awaiting!"
文本仍然卡在默认Loading...
我已经正确地模拟了服务,并且count
变量甚至被正确记录为42
! 但是this.state.count
仍为-1
因此不显示: ${this.state.count} Notifications Awaiting
它的${this.state.count} Notifications Awaiting
仍然显示Loading...
因此测试失败。
1)我尝试在延迟中添加1000。
2)在测试中使用setTimeout尝试。
3)尝试了jest.useFakeTimers();
和jest.runAllTimers();
但是没有任何工作,即使count
设置为42,组件内部的count
仍然保持在-1
。在我看来,我的测试在状态完成设置之前运行了吗?
import React from 'react';
import NotificationsService from '../services/NotificationsService';
export default class componentName extends React.Component {
constructor(...args) {
super(...args);
this.state = {
count: -1
}
}
async componentDidMount () {
let { count } = await NotificationsService.GetNotifications();
console.log('count:', count);
this.setState({
count
});
}
componentDidUpdate() {
console.log('componentDidUpdate:', this.state);
}
render() {
return (
<div className="mt-3 mb-2">
<div className="notifications">
{this.state.count != -1 ? `${this.state.count} Notifications Awaiting` : `Loading...`}
</div>
</div>
)
}
}
import { delay } from 'redux-saga';
export default {
async GetNotifications() {
console.warn("REAL NOTIFICATION SERVICE! CONTACTING APIS!");
await delay(1000);
return { count: 42 };
}
}
let count = 0;
export default {
__setCount(_count) {
count = _count;
},
async GetNotifications() {
console.warn("GOOD JOB! USING MOCK SERVICE");
return { count };
}
}
最后...
import React from 'react';
import renderer from 'react-test-renderer';
import delay from 'redux-saga';
import NotificationsViewer from '../NotificationsViewer';
jest.mock('../../services/NotificationsService');
const notificationService = require('../../services/NotificationsService').default;
describe('The notification viewer', () => {
beforeAll(() => {
notificationService.__setCount(42);
});
it('should display the correct number of notifications', async() => {
const tree = renderer
.create(
<NotificationsViewer/>
);
await delay();
const instance = tree.root;
const component = instance.findByProps({className: `notifications`});
const text = component.children[0];
console.log('text is:', text);
expect(text).toEqual('42 Notifications Awaiting!');
});
})
问题是await delay()
不能让所有React生命周期方法像componentDidMount
实例化/被调用。
我不得不使用Enzyme
,尽管由于很多开放的bug问题,作者没有推荐它。
使用Enzyme我可以确保调用componentDidMount
,从而使用模拟服务将count
的状态设置为42
。
我还需要安装以下软件包:
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
import React from 'react';
import renderer from 'react-test-renderer';
import Adapter from 'enzyme-adapter-react-16';
import { shallow, configure } from 'enzyme';
configure({adapter: new Adapter()});
import NotificationsViewer from './NotificationsViewer';
jest.mock('../services/NotificationsService');
const notificationService = require('../services/NotificationsService').default;
notificationService.default = jest.fn();
describe('The notification viewer', () => {
beforeAll(() => {
notificationService.__setCount(42);
});
// it('pass', () => {});
it('should display the correct number of notifications', async() => {
const tree = renderer.create(<NotificationsViewer />);
const wrapper = shallow(<NotificationsViewer />);
const instance = tree.root;
await wrapper.instance().componentDidMount();
const component = instance.findByProps({className: `notifications`});
const text = component.children[0];
console.log('text is:', text);
expect(text).toEqual('42 Notifications Awaiting');
});
})
实际上,真正的问题是在isomorphic-react/src/components/__tests__/NotificationsViewer.js
文件中。 delay
是以错误的方式导入的,这导致测试时出错。
如果像这样导入delay
: import { delay } from 'redux-saga'
修复问题。 = d
也许你的describe
也需要是一个异步函数? 需要在async
范围内声明await
语句,不是吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.