我的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);
})
问题是我的测试完成,失败,在我的代码中的promise解析之前,以及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);
});
})
有没有什么方法可以重写我的代码来避免这种情况?或者是否有其他模式我可以用于此方案来测试我的异步代码?谢谢!
答案 0 :(得分:0)
首先编辑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);
答案 1 :(得分:0)
修改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})
})
}
现在,您可以在测试中获得承诺,并允许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测试中返回一个promise时,Jest会尝试解决它。如果成功解决了承诺,将调用then()
。