我将继续关注此Jest test tutorial on Pluralsight here。而且我写的代码与作者完全一样,但是由于某种原因,我的测试没有通过。
我对作者回购请求的请求:https://github.com/danielstern/isomorphic-react/pull/19
我有一个简单的React组件,它通过对count
中的服务进行异步/等待调用来更新其componentDidMount
状态。
{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
,但仍然显示Loading...
,因此测试失败。
1)我尝试将1000加到延迟中。
2)在测试内部使用setTimeout进行了尝试。
3)尝试过jest.useFakeTimers();
和jest.runAllTimers();
无论什么都不起作用,即使count
设置为42,组件内部的-1
仍停留在count
处。在我看来,我的测试在状态设置完毕?
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!');
});
})
答案 0 :(得分:1)
问题是await delay()
无法让所有componentDidMount
之类的React生命周期方法实例化/被调用。
尽管由于很多开放的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');
});
})
答案 1 :(得分:1)
实际上,真正的问题出在isomorphic-react/src/components/__tests__/NotificationsViewer.js
文件中。 delay
的导入方式错误,导致测试出错。
如果像这样导入delay
:import { delay } from 'redux-saga'
可解决问题。 = D
答案 2 :(得分:0)
也许您的describe
还需要是一个异步函数? await
语句需要在async
范围内声明,不是吗?