Len*_*man 7 fetch reactjs jestjs enzyme
我是 React 和任何 JavaScript 测试框架的新手。
我有一个简单的组件,可以从 API 检索项目并将其显示在屏幕上。
函数 getItems() 是从 componentWillMount 调用的。
是否可以等到 getItems() 完成后再做出断言?
项目详细信息.js
class ItemDetails extends Component {
constructor(props) {
super(props);
this.state = {
details: ''
}
}
componentWillMount() {
this.getItem();
}
getItem() {
const itemId = this.props.match.params.id;
fetch(`/api/items/${itemId}`)
.then(res => res.json())
.then(details => this.setState({ details }));
}
render() {
const details = this.state.details;
return (
<div>
<h1>{details.title}</h1>
...
</div>
);
}
}
export default ItemDetails;
Run Code Online (Sandbox Code Playgroud)
ItemDetails.test.js
describe('ItemDetails', () => {
it('should render a div with title', () => {
const details = {
_id: 1,
title: 'ItemName'
};
fetch.mockResponseOnce(JSON.stringify(details));
const wrapper = mount(<ItemDetails match={{ params: {id: 1} }} />);
expect(wrapper.find('div').find('h1').text()).toBe('ItemName');
});
});
Run Code Online (Sandbox Code Playgroud)
上面的答案有效,但它需要测试实现细节:
.instance())的实例并调用update()是测试的味道,在我看来,这些测试对被测代码的工作方式了解太多,它不是在测试行为,而是在测试实现您真正想要的是等待所有承诺得到解决,而不访问这些承诺的句柄(这会破坏隐私)。尝试这个
const wait = () => new Promise(resolve => setTimeout(resolve));
it('does something', () => {
renderFnThatCallsAPromiseInternally();
return wait().then(() => {
expect(somethingDependentOnPromiseExecution).to.be.present();
});
});
Run Code Online (Sandbox Code Playgroud)
这将等待所有内部承诺解决,前提wait是在调用排队承诺(呈现组件)的代码之后调用。原因在于 JS 事件循环的工作方式,它很挑剔,但 Jake Archibald 在本次演讲中对此进行了很好的解释:https ://www.youtube.com/watch?v=cCOL7MC4Pl0 。
希望有帮助。
你能尝试一下吗:
describe('ItemDetails', () => {
it('should render a div with title', () => {
const details = {
_id: 1,
title: 'ItemName'
};
fetch.mockResponseOnce(JSON.stringify(details));
const wrapper = shallow(<ItemDetails match={{ params: {id: 1} }} />);
// manually call function
wrapper.instance().getItem();
// update to re-render component
wrapper.update();
expect(wrapper.find('div').find('h1').text()).toBe('ItemName');
});
});
Run Code Online (Sandbox Code Playgroud)
如果它没有帮助,我认为你需要从你的函数返回 Promise (基于这个例子):
getItem() {
const itemId = this.props.match.params.id;
return fetch(`/api/items/${itemId}`)
.then(res => res.json())
.then(details => this.setState({ details }));
}
describe('ItemDetails', () => {
it('should render a div with title', () => {
const details = {
_id: 1,
title: 'ItemName'
};
fetch.mockResponse(JSON.stringify(details)); //response gets called twice
const wrapper = mount(<ItemDetails match={{ params: {id: 1} }} />);
// return Promise so Jest will wait until it's finished
return wrapper.instance().getItem().then(() => {
wrapper.update();
}).then(() => {
expect(wrapper.find('div').find('h1').text()).toBe('ItemName');
})
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9138 次 |
| 最近记录: |