[英]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.