我正在使用chai-as-promised来测试一些承诺。我的问题是我不确定如何在一次测试中使用多个期望语句。为了使expect().to.be.fulfilled
正常工作,我需要将其返回,如下所示:
it('test', () => {
return expect(promise).to.be.fulfilled
}
...或使用notify
,如下所示:
it('test', (done) => {
expect(promise).to.be.fulfilled.notify(done)
}
问题来自于我需要检查的另一件事,例如某个函数被调用,如下所示:
it('test', (done) => {
var promise = doSomething()
expect(sinon_function_spy.callCount).to.equal(1)
expect(promise).to.be.fulfilled.notify(done)
})
这里的问题是,因为doSomething()
是异步的,所以当我调用sinon_function_spy
时,可能还没有发生对expect
的调用,这使得此测试变得不稳定。如果我使用then
,就像这样:
it('test', (done) => {
var promise = doSomething()
promise.then(() => {
expect(sinon_function_spy.callCount).to.equal(1)
})
expect(promise).to.be.fulfilled.notify(done)
})
然后测试技术按预期传递并失败,但由于then
调用中抛出的异常导致promise被拒绝,因此会失败。同样,如果我有一个承诺预计拒绝的情况:
it('test', (done) => {
var promise = doSomething()
promise.then(() => {
expect(sinon_function_spy.callCount).to.equal(1)
})
expect(promise).to.be.rejected.notify(done)
})
然后,sinon_function_spy
上的检查永远不会被调用,因为承诺被拒绝,并且没有调用then
。
如何让两个expect
语句可靠地执行并返回正确的值?
答案 0 :(得分:2)
如果您使用mocha或jest作为测试框架,则可以在then()
块中按预期返回承诺:
it('test', () => {
return doSomething().then( () => {
expect(sinon_function_spy.callCount).to.equal(1);
});
});
此测试不会结束,直到承诺成功完成且expect
已运行。如果您正在使用茉莉花,则可以使用jasmine-promises
包来获得相同的功能。
对于相反的情况,我建议创建一个扭转承诺极性的包装器:
function reverse( promise ) {
//use a single then block to avoid issues with both callbacks triggering
return promise.then(
() => { throw new Error("Promise should not succeed"); }
e => e; //resolves the promise with the rejection error
);
}
现在你可以做到
it('test', () => {
return reverse( doSomethingWrong() ).then( error => {
expect( error.message ).to.equal("Oh no");
});
});
答案 1 :(得分:1)
如果想要声明Promise已完成和,则按预期执行调用,您实际上并不需要将第一部分作为断言。如果Promise拒绝,则mocha测试用例本身将失败:
it('test', () => {
return doSomething()
.then(() => {
expect(sinon_function_spy.callCount).to.equal(1)
});
});
如果doSomething()
返回的Promise拒绝,那么测试用例也是如此。如果expect
断言失败,那么失败的断言也会使测试用例失败。如果你想更明确一点:
it('test', () => {
return doSomething()
.then(() => {
expect(sinon_function_spy.callCount).to.equal(1)
}, err => {
expect(err).to.not.exist;
});
});
...你可以发现错误。请注意,对于具有两个回调的then
这种风格,第一个回调中的断言失败将不会到达第二个回调,因此它只是Mocha看到失败的断言。
以下是您如何做出预期失败的承诺:
it('test', () => {
return doSomething()
.then(() => {
throw new Error('Promise should not have resolved');
}, err => {
expect(err).to.exist;
expect(sinon_function_spy.callCount).to.equal(1)
});
})
答案 2 :(得分:1)
一种实现多重期望的方法
it('should fail if no auth', () => {
const promise = chai.request(server).get('/albums');
return expect(promise).to.be.rejected.then(() => {
return promise.catch(err => {
expect(err).not.to.be.null;
expect(err.response).to.have.status(401);
expect(err.response).to.be.a.json;
});
});
});