2016-02-11 5 views
1

У меня есть функция isMember, как показано ниже;Шпион не мог отслеживать при проверке функции Async с помощью Mocha и Sinon

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 всегда ложно. Как я могу добиться того, что мой шпион будет ждать, пока next() вызывается в функции isMember?

ответ

0

Вам нужно поставить done() внутри обратного вызова из-за того, как цикл событий работает в javascript. Сначала выполняется весь синхронный код, а затем выполняются все ожидающие задачи async.

У 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); 
    }); 
}); 
+0

Правильно, но функция isMember не возвращает обещание по дизайну. Это файл политики sails.js. –

+0

Затем вы можете создать свой собственный обратный вызов, используя isMember (req, res, function() {next()}) –

0

В Sinon fakeTimers заменить глобальную функцию SetTimeout, но ваш код не содержит какой-либо функции тайм-аута.

Вы можете использовать функцию setTimeout для задержки выполнения ожидания, а затем разрешить ваш тест, вызвав done() внутри setTimeout. Вы можете попробовать что-то вроде этого:

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