Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing Mocha测试不会使用Sinon存根解决承诺问题_Unit Testing_Promise_Mocha.js_Sinon_Chai - Fatal编程技术网

Unit testing Mocha测试不会使用Sinon存根解决承诺问题

Unit testing Mocha测试不会使用Sinon存根解决承诺问题,unit-testing,promise,mocha.js,sinon,chai,Unit Testing,Promise,Mocha.js,Sinon,Chai,我正在使用Mocha测试一个包含异步方法的方法。我正在与西农断绝这种依赖关系,并返回一个坚定的承诺。但承诺从未得到解决,或者至少在运行断言时,它还没有得到解决 这是正在测试的方法 功能识别(特征){ //这将被成功调用 userService.get().then(函数(用户){ //代码永远不会到达这里 set(user).then(function()){ //做点什么 },函数(){ //处理错误 }); }); } 这是测试 it('应该识别一个有效的电子邮件地址',函数(){ var

我正在使用Mocha测试一个包含异步方法的方法。我正在与西农断绝这种依赖关系,并返回一个坚定的承诺。但承诺从未得到解决,或者至少在运行断言时,它还没有得到解决

这是正在测试的方法

功能识别(特征){
//这将被成功调用
userService.get().then(函数(用户){
//代码永远不会到达这里
set(user).then(function()){
//做点什么
},函数(){
//处理错误
});
});
}
这是测试

it('应该识别一个有效的电子邮件地址',函数(){
var user={email:'test@example.com' };
var getUserStub=sinon.stub(userService,“get”);
var setUserStub=sinon.stub(userService,“set”);
var userReturn={email:'test@example.com,网址:['http://some.url.com'] };
getUserStub.returns(Promise.resolve(userReturn));
//正在测试的方法
识别控制器。识别(用户);
sinon.assert.calledOnce(userService.get);//工作正常
sinon.assert.calledOnce(userService.set);//失败
getUserStub.restore();
});

userService.set上的断言失败,它表示调用了0次。我做错了什么?

我终于找到了问题所在

承诺本质上是异步的,但sinon调用是同步的

看这个

发生了什么:

  • 调用
    identifyController.identify(用户)
    
    • 它将调用
      get
      ,这将返回一个承诺,即异步
  • 程序的主线程仍将运行,因此您的两个
    sinon.assert.calledOnce
    调用将按顺序同步进行
  • get
    自行解析并调用
    set
    时,由于承诺是非阻塞的,断言将已经执行,因此将失败

    所以,你可以这样做:

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

    我终于找到了问题所在

    承诺本质上是异步的,但sinon调用是同步的

    看这个

    发生了什么:

  • 调用
    identifyController.identify(用户)
    
    • 它将调用
      get
      ,这将返回一个承诺,即异步
  • 程序的主线程仍将运行,因此您的两个
    sinon.assert.calledOnce
    调用将按顺序同步进行
  • get
    自行解析并调用
    set
    时,由于承诺是非阻塞的,断言将已经执行,因此将失败

    所以,你可以这样做:

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

    嗨,谢谢你的回复。我添加了返回语句和catch块,但不幸的是控制台中没有错误。我假设
    userService.get()
    是一个thenable,对吗?我对你的问题感到困惑。我正在删除这个方法,并使它返回一个已确定的承诺。所以,那么,它必须是,对吗?对不起,我应该问“你正在使用吗?”不,先生,我应该吗?嗨,谢谢你的回答。我添加了返回语句和catch块,但不幸的是控制台中没有错误。我假设
    userService.get()
    是一个thenable,对吗?我对你的问题感到困惑。我正在删除这个方法,并使它返回一个已确定的承诺。那么,它必须是,对吗?对不起,我应该问“你在使用吗?”不,先生,我应该是吗?
    userService
    是一个全局变量吗?你可能在这里碰到了什么。userService是一个模块,但在实时代码和测试文件中都需要它。也许它们是不同的实例?我们在模块中使用browserify,所以我验证了两个文件中的userService是相同的。
    userService
    是全局变量吗?您可能在这里遇到了一些问题。userService是一个模块,但在实时代码和测试文件中都需要它。也许它们是不同的实例?我们在模块中使用browserify,所以我验证了两个文件中的userService是相同的。