Mocha 测试不会解决使用 Sinon 存根的承诺
Mocha test will not resolve promise using Sinon stub
我正在使用 Mocha 测试一个内部有异步方法的方法。我正在用 Sinon 消除这种依赖,并返回一个已解决的承诺。但是承诺永远不会解决,或者至少当断言是 运行 时它还没有解决。
下面是正在测试的方法
function identify(traits) {
//THIS GETS CALLED SUCCESSFULLY
userService.get().then(function(user){
//CODE NEVER REACHES HERE
userService.set(user).then(function(){
//do something
}, function(){
//handle error
});
});
}
这是测试
it('should identify a valid email address', function(){
var user = { email: 'test@example.com' };
var getUserStub = sinon.stub(userService, "get");
var setUserStub = sinon.stub(userService, "set");
var userReturn = { email: 'test@example.com', urls: ['http://some.url.com'] };
getUserStub.returns(Promise.resolve(userReturn));
//THE METHOD UNDER TEST
identifyController.identify(user);
sinon.assert.calledOnce(userService.get); //WORKS FINE
sinon.assert.calledOnce(userService.set); //FAILS
getUserStub.restore();
});
userService.set 断言失败,它说它被调用了 0 次。我做错了什么?
终于找到问题了
Promise 本质上是异步的,但 sinon 调用是同步的。
看到这个code pen。
会发生什么:
- 你打电话给
identifyController.identify(user);
- 它会调用
get
,returns 一个 promise,它是 asyncrhonous。
- 程序的主线程仍将是 运行,因此您的两个
sinon.assert.calledOnce
调用将按顺序发生,同步
到 get
自行解析并调用 set
时,因为承诺是 non-blocking,断言已经执行,所以它会失败。
所以,你可以这样做:
function identify(traits) {
return userService.get().then(function(user){
console.log('get');
userService.set(user).then(function(){
console.log('set');
//do something
});
});
}
并更改此:
identify(user).then(function(){
sinon.assert.calledOnce(myObj.get); //WORKS FINE
sinon.assert.calledOnce(myObj.set); //WORKS FINE NOW
});
我正在使用 Mocha 测试一个内部有异步方法的方法。我正在用 Sinon 消除这种依赖,并返回一个已解决的承诺。但是承诺永远不会解决,或者至少当断言是 运行 时它还没有解决。
下面是正在测试的方法
function identify(traits) {
//THIS GETS CALLED SUCCESSFULLY
userService.get().then(function(user){
//CODE NEVER REACHES HERE
userService.set(user).then(function(){
//do something
}, function(){
//handle error
});
});
}
这是测试
it('should identify a valid email address', function(){
var user = { email: 'test@example.com' };
var getUserStub = sinon.stub(userService, "get");
var setUserStub = sinon.stub(userService, "set");
var userReturn = { email: 'test@example.com', urls: ['http://some.url.com'] };
getUserStub.returns(Promise.resolve(userReturn));
//THE METHOD UNDER TEST
identifyController.identify(user);
sinon.assert.calledOnce(userService.get); //WORKS FINE
sinon.assert.calledOnce(userService.set); //FAILS
getUserStub.restore();
});
userService.set 断言失败,它说它被调用了 0 次。我做错了什么?
终于找到问题了
Promise 本质上是异步的,但 sinon 调用是同步的。
看到这个code pen。
会发生什么:
- 你打电话给
identifyController.identify(user);
- 它会调用
get
,returns 一个 promise,它是 asyncrhonous。
- 它会调用
- 程序的主线程仍将是 运行,因此您的两个
sinon.assert.calledOnce
调用将按顺序发生,同步
到 get
自行解析并调用 set
时,因为承诺是 non-blocking,断言已经执行,所以它会失败。
所以,你可以这样做:
function identify(traits) {
return userService.get().then(function(user){
console.log('get');
userService.set(user).then(function(){
console.log('set');
//do something
});
});
}
并更改此:
identify(user).then(function(){
sinon.assert.calledOnce(myObj.get); //WORKS FINE
sinon.assert.calledOnce(myObj.set); //WORKS FINE NOW
});