我曾经有过下面的代码中承诺:测试承诺
function makeCall(userInfo) {
api.postUser(userInfo).then(response => {
utils.redirect(response.url);
})
// other logic
return somethingElse;
}
,我能够写一个测试,是这样的:
const successPromise = Promise.resolve({ url: 'successUrl' })
beforeEach(function() {
sinon.stub(api.postUser).returns(successPromise);
}
afterEach(function() {
api.postUser.restore();
}
it "calls API properly and redirects" do
makeCall({});
expect(api.postUser).calledWith(userInfo).toBe(true);
successPromise.then(() => {
expect(utils.redirect.calledWith('successUrl')).toBe(true);
done();
}
emd
,一切都是绿色的。现在
,我不得不添加另一个承诺,使另外一个外部调用,这样做的API postUser调用之前,所以我的代码如下所示:
function makeCall(names) {
fetchUserData(names).then(userData => {
return api.postUser(userData).then(response => {
utils.redirect(response.url);
})
})
// other logic
return somethingElse;
}
其中fetchUseData是许多承诺,比如像链:
function fetchNames(names) {
// some name regions
return Promise.all(names);
}
function fetchUserData(names) {
fetchUsersByNames(names).then(users => {
// For now we just choose first user
{
id: users[0].id,
name: users[0].name,
}
});
}
而且我的测试失败了。我正在尝试了解如何更改我的测试,以确保我仍在测试是否正确执行了最终的API调用,并且重定向也已完成。我想存根fetchUserData(names)
,以防止做这个HTTP调用。
您没有使用正确的承诺。你的代码没有一个'return'语句,它应该有几个(或者至少应该使用箭头函数,这样你不需要它们,你不这样做)。您不断将自由浮动的代码块称为“我的代码”。什么是调用该代码?你的测试不应该调用它吗?在您的代码已经运行到其他地方后,它们似乎正在观察一些结果。 – JLRishe
尝试返回内部承诺(添加'return')以创建承诺链。 – TiagoLr
@JLRishe更新。我主要关心的是我应该把“done()”放在哪里,或者我应该做什么,这样承诺就会被扼杀和评估。 –