[英]How to mock a function of React Component and mount the component?
我有一個使用fetch API獲取帖子的react組件。 現在,在進行“開玩笑的測試”時,我想模擬訪存API方法以從文件返回json數據。 通過查找類計數,安裝要測試的組件以計算帖子數。 下面是代碼。
測試文件代碼
import React from 'react';
import { mount } from 'enzyme';
import dummyjson from '../dummydata.json';
import DemoApp from '../index';
describe('xxxx test component', () => {
it('first test', async () => {
global.fetch = jest.fn(() => Promise.resolve(dummyjson));
const wrapper = shallow(<DemoApp />, { disableLifecycleMethods: true });
expect(wrapper.state('isLoaded')).toBe(false);
await wrapper.instance().loadPosts();
expect(wrapper.state('isLoaded')).toBe(true);
});
});
反應組件代碼
import React from 'react';
/* eslint class-methods-use-this: ['error', { 'exceptMethods': ['fetch'] }] */
export default class DemoApp extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
items: [],
};
}
componentDidMount() {
this.loadPosts().then(
(result) => {
this.setState({
isLoaded: true,
items: result,
});
},
(error) => {
this.setState({
isLoaded: true,
error,
});
},
);
}
loadPosts() {
return fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json()).then(result => result)
.catch(error => error);
}
render() {
const { error, isLoaded, items } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
}
return (
<div>
{items.map(item => <div className="somecssclass"> {item.title} {item.title}</div>)}
</div>
);
}
}
下面是dummydata json
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
}
]
即使我在react組件類文件中為fetch方法提供了以下異常,但我仍在錯誤/警告下出現錯誤。 / * eslint class-methods-use-this:['error',{'exceptMethods':['fetch']}] * /
我們如何解決此警告/錯誤?
非常感謝您的幫助。 謝謝。
有比賽條件。 loadPosts
是異步的,而測試是同步的,並且沒有承諾鏈等待fetch
承諾鏈完成。
控制流程和測試方法存在問題。 loadPosts
需要返回一個promise,因此可以將其鏈接起來:
loadPosts() {
return fetch('https://jsonplaceholder.typicode.com/posts')...;
}
進行單元測試的一種正確方法是在一個測試中測試loadPosts
並直接loadPosts
進行測試:
it('...', async () => {
global.fetch = jest.fn(() => Promise.resolve(dummyjson));
const wrapper = shallow(<DemoApp />, { disableLifecycleMethods: true });
expect(wrapper.state('isLoaded').toBe(false);
await wrapper.instance().loadPosts();
expect(wrapper.state('isLoaded').toBe(true);
});
在另一個測試中,可以對loadPosts
進行存根/ loadPosts
並斷言在componentDidMount
調用了它。
還要注意, global.fetch =
會一勞永逸地替換它。 最好使用jest.stub
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.