【问题标题】:Spy could not track on Async function test with Mocha and SinonSpy 无法使用 Mocha 和 Sinon 跟踪异步功能测试
【发布时间】:2016-02-11 16:59:15
【问题描述】:

我有如下 isMember 函数;

function isMember(req, res, next) {
MyService.GetUserAsync(authCookie)
        .then(function (user) {
            next();
        })
        .catch(function (err) {
            if (err.status === 400) {
                return res.redirect("/notAllowed");
            }
            else {
                return next(err);
            }
        });
}

我的测试如下;

 beforeEach(function () {        
            // Overwrite the global timer functions (setTimeout, setInterval) with Sinon fakes
            this.clock = sinon.useFakeTimers();
        });
        afterEach(function () {
            // Restore the global timer functions to their native implementations
            this.clock.restore();
        });

 it.only("pass authentication and set authCookie", function (done) {
            var user = {
                userNameField: "fakeUserName"
            };
            sinon.stub(MyService, "GetUserAsync").returns(Promise.resolve(user));            
            var spyCallback = sinon.spy();
            var req {};
            var res = {};
            isMember(req, res, spyCallback);
            // Not waiting here!
            this.clock.tick(1510);
            // spyCallback.called is always false
            expect(spyCallback.called).to.equal(true);           
            done();
        });

由于某种原因,this.clock.tick 不起作用,spyCallback.called 始终为假。 如何实现我的间谍将等到在 isMember 函数中调用next()

【问题讨论】:

    标签: javascript unit-testing mocha.js sinon


    【解决方案1】:

    sinon fakeTimers 替换了全局 setTimeout 函数,但您的代码不包含任何超时函数。

    您可以使用 setTimeout 函数来延迟期望的执行,然后通过在 setTimeout 中调用 done() 来解决您的测试。你可以试试这样:

    setTimeout(function () {
      expect(spyCallback.called).to.equal(true);
      done();
    }, 0);
    

    【讨论】:

      【解决方案2】:

      您需要将 done() 放在回调中,因为事件循环在 javascript 中是如何工作的。首先执行所有同步代码,然后执行所有挂起的异步任务。

      Mocha 支持承诺。如果您从it() 返回一个承诺,它将被等待。所以,你可以做类似的事情

      it.only("pass authentication and set authCookie", function (done) {
          var user = {
              userNameField: "fakeUserName"
          };
          sinon.stub(MyService, "GetUserAsync").returns(Promise.resolve(user));            
          var spyCallback = sinon.spy();
          var req {};
          var res = {};
          return isMember(req, res, spyCallback).then(function () {
              expect(spyCallback.called).to.equal(true); 
          });   
      });
      

      【讨论】:

      • 是的,但是 isMember 函数不会返回设计的承诺。这是一个sails.js 策略文件。
      • 然后,您可以使用 isMember(req, res, function() { next() }) 创建自己的回调函数
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 2018-09-03
      • 1970-01-01
      • 2018-07-08
      • 2017-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多