首页 文章

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

提问于
浏览
1

我正在使用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

    我终于找到了问题 .

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

    code pen .

    怎么了:

    • 你拨打 identifyController.identify(user);

    • 它将调用 get ,它返回一个promise,即 asyncrhonous .

    • 程序的主线程仍将运行,因此您的两个 sinon.assert.calledOnce 调用将按顺序进行, synchronously

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

相关问题