我是 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;
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');
});
});
上面的答案有效,但它需要测试实现细节:
- 根据经验,访问包装器的实例(
.instance()
)并调用update()
在我看来,测试的味道对被测代码的工作方式了解太多,它不是在测试行为,而是在测试实现
- 让方法返回一个承诺并在执行期望之前等待该承诺会破坏方法的隐私:它使代码难以重构
您真正想要的是等待所有承诺得到解决,而不访问这些承诺的句柄(这会破坏隐私)。尝试这个
const wait = () => new Promise(resolve => setTimeout(resolve));
it('does something', () => {
renderFnThatCallsAPromiseInternally();
return wait().then(() => {
expect(somethingDependentOnPromiseExecution).to.be.present();
});
});
这将等待所有内部承诺得到解决,前提是wait
在调用将 Promise 排入队列(呈现组件)的代码之后调用。原因在于 JS 事件循环的工作方式,它很挑剔,但 Jake Archibald 在本次演讲中对此进行了很好的解释:https://www.youtube.com/watch?v=cCOL7MC4Pl0 https://www.youtube.com/watch?v=cCOL7MC4Pl0.
希望有帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)