摩卡测试不会使用Sinon存根解决承诺

时间:2016-01-06 15:09:02

标签: unit-testing promise mocha sinon chai

我正在使用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次。我做错了什么?

1 个答案:

答案 0 :(得分:0)

我终于找到了问题。

Promise本质上是异步的,但是sinon调用是同步的。

请参阅此code pen

会发生什么:

  1. 你致电identifyController.identify(user);
    • 它会调用get,它会返回一个承诺, asyncrhonous
  2. 该计划的主要线程仍在运行,因此您的两个sinon.assert.calledOnce来电将按顺序进行,同步
  3. get解析自身并调用set时,由于promises是非阻塞的,因此断言已经执行,因此它将失败。

    所以,你可以这样做:

    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
    });