[英]react testing function with asynchronous setState call
我的React组件中有以下功能
changeProject(project) {
const buildProjectValues = [];
BambooService.GetBuilds(project).then((res) => {
res.map(build => {
buildProjectValues.push({'label':build.searchEntity.planName, 'value':build.searchEntity.id});
});
this.setState({buildValues:buildProjectValues})
})
}
与关联的测试:
it('should set buildValues state property to returned array from API call', () => {
const wrapper = mount(<RepoForm projectValues={projectOptions} />);
const instance = wrapper.instance();
nock('https://myurl.api.com')
.get('/builds?projectKey=KEY')
.reply(200, buildMock)
instance.changeProject('KEY');
expect(instance.state.buildValues).to.equal(buildMock);
})
问题是在我的代码中的诺言得以解决之前,我的测试以失败告终,而且setState还是异步的!
我已经尝试过使用setImmediate,如下所示,但结果相同。
it('should set buildValues state property to returned array from API call', () => {
const wrapper = mount(<RepoForm projectValues={projectOptions} />);
const instance = wrapper.instance();
nock('https://myurl.api.com')
.get('/builds?projectKey=KEY')
.reply(200, buildMock)
instance.changeProject('KEY');
setImmediate(() => {
expect(instance.state.buildValues).to.equal(buildMock);
});
})
有什么办法可以重写我的代码来避免这种情况? 还是在这种情况下可以使用其他模式来测试异步代码? 谢谢!
首先编辑changeProject()以返回在测试中使用它的承诺:
changeProject(project) {
const buildProjectValues = [];
return BambooService.GetBuilds(project).then((res) => {
res.map(build => {
buildProjectValues.push({
'label':build.searchEntity.planName,
'value':build.searchEntity.id
});
});
this.setState({buildValues:buildProjectValues})
})
}
然后在测试中,将您的断言添加到then()
:
it('should set buildValues state property to returned array from API call', () => {
const wrapper = mount(<RepoForm projectValues={projectOptions} />);
const instance = wrapper.instance();
nock('https://myurl.api.com')
.get('/builds?projectKey=KEY')
.reply(200, buildMock)
instance.changeProject('KEY')
.then(() => {
expect(instance.state.buildValues).to.equal(buildMock);
});
})
您也可以使用await
代替then()
await instance.changeProject('KEY');
expect(instance.state.buildValues).to.equal(buildMock);
修改changeProject()
以返回承诺:
changeProject(project) {
const buildProjectValues = [];
return BambooService.GetBuilds(project).then((res) => {
res.map(build => {
buildProjectValues.push({'label':build.searchEntity.planName, 'value':build.searchEntity.id});
});
this.setState({buildValues:buildProjectValues})
})
}
现在,您可以在测试中获得promise,并允许Jest在调用expect()
之前解决它:
it('should set buildValues state property to returned array from API call', () => {
const wrapper = mount(<RepoForm projectValues={projectOptions} />);
const instance = wrapper.instance();
nock('https://myurl.api.com')
.get('/builds?projectKey=KEY')
.reply(200, buildMock)
return instance.changeProject('KEY')
.then(() => {
expect(instance.state.buildValues).to.equal(buildMock);
});
})
当您从Jest测试返回承诺时,Jest将尝试解决它。 如果成功解决了诺言, then()
将调用then()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.