【问题标题】:Mocha test will not resolve promise using Sinon stubMocha 测试不会使用 Sinon 存根解决 Promise
【发布时间】:2016-01-06 15:09:02
【问题描述】:

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

【问题讨论】:

  • userService 是全局变量吗?
  • 您可能在这里遇到了一些问题。 userService 是一个模块,但它在实时代码和测试文件中都是必需的。也许它们是不同的实例?
  • 我们正在为我们的模块使用 browserify,所以我验证了两个文件中的 userService 是相同的。

标签: unit-testing promise mocha.js sinon chai


【解决方案1】:

我终于找到了问题。

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

看到这个code pen

会发生什么:

  1. 您拨打identifyController.identify(user);
    • 它将调用get,它返回一个异步的promise。
  2. 程序的主线程仍将运行,因此您的两个 sinon.assert.calledOnce 调用将按顺序发生,同步

get 自行解析并调用set 时,因为promise 是非阻塞的,所以断言已经被执行,所以它会失败。

所以,你可以这样做:

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

【讨论】:

  • 您好,感谢您的回复。我添加了 return 语句和 catch 块,但不幸的是控制台中没有错误。
  • 我假设 userService.get() 是一个 thenable,对吗?
  • 我对你的问题感到困惑。我正在对该方法进行存根,并使其返回一个已解决的承诺。那么,它必须是,对吧?
  • 对不起,我应该问“你在用promisified version of sinon吗?”
  • 不,先生,我应该是吗?
猜你喜欢
  • 1970-01-01
  • 2015-12-01
  • 2017-10-13
  • 1970-01-01
  • 2017-06-05
  • 2017-10-07
  • 2018-03-15
  • 1970-01-01
  • 2013-09-06
相关资源
最近更新 更多