我有一个使用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']}] * /
我们如何解决此警告/错误?
我们非常感谢您的帮助。 谢谢。
答案 0 :(得分:0)
存在比赛条件。 <h2>Search/Filter Dropdown</h2>
<p>Click on the button to open the dropdown menu, and use the input field to search for a specific dropdown link.</p>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Dropdown</button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
<a href="#about"><i class="flag a"></i><span>About</span></a>
<a href="#base"><i class="flag b"></i><span>Base</span></a>
<a href="#blog"><i class="flag b"></i><span>Blog</span></a>
<a href="#contact"><i class="flag c"></i><span>Contact</span></a>
<a href="#custom"><i class="flag c"></i><span>Custom</span></a>
<a href="#support"><i class="flag s"></i><span>Support</span></a>
<a href="#tools"><i class="flag t"></i><span>Tools</span></a>
</div>
</div>
是异步的,而测试是同步的,并且没有保证链等待const LoadableComponent = Loadable({
loader: () => import('components/Shared/Logo/Logo'),
loading: () => <div>loading</div>, // pass component, not jsx
});
保证链完成。
控制流程和测试方法存在问题。 loadPosts
需要返回承诺,因此可以将其链接起来:
fetch
单元测试的一种正确方法是在一项测试中测试loadPosts
并直接对其进行测试:
loadPosts() {
return fetch('https://jsonplaceholder.typicode.com/posts')...;
}
在另一个测试中,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
会一劳永逸地替换它。最好使用componentDidMount
模拟它。