簡體   English   中英

如何在一個restify HTTP處理程序中測試我的異步代碼?

[英]How can I test my asynchronous code in a restify HTTP handler?

我在Restify項目中有一個處理HTTP GET請求的函數。 經過一些處理后,它使用Sequelize查找當前會話的用戶實體。 User.findOne函數返回一個promise,並根據該promise的結果,我發送一個200或404的HTTP響應。

static getMe(req, res, next) {
    const userInfo = BaseController.getUserSession(req);

    // hard to test this part
    User.findOne({
      where: {email: userInfo.email}
    }).then(function(user) {
      if (user) BaseController.respondWith200(res, user);
      else BaseController.respondWith404(res, 'User not found.');
    }, function(error) {
      BaseController.respondWith404(res, error);
    }).then(function() {
      return next();
    });
}

我已經嘗試了幾個不同的庫來幫助測試,所以如果這是一個混亂的事情,我很抱歉。 這是我的beforeEach函數,用於我的測試:

const usersFixture = [
  {id:2, email:'ozzy@osbourne.com', facebookId:54321, displayName: 'Ozzy Osbourne'},
  {id:3, email:'zakk@wylde.com', facebookId:34521, displayName: 'Zakk Wylde'},
  {id:4, email:'john@lennon.com', facebookId:12453, displayName: 'John Lennon'}
];

this.findOneSpy = sinon.spy(function(queryObj) {
  return new Promise(function(resolve, reject) {
    const user = usersFixture.find(function(el) { return el.email === queryObj.where.email });
    if (user) resolve(user);
    else resolve(null);
  });
});

this.respondWith200Spy = sinon.spy(function(res, data) {});
this.respondWith400Spy = sinon.spy(function(res, error) {});
this.respondWith404Spy = sinon.spy(function(res, error) {});

this.controller = proxyquire('../../controllers/user-controller', {
  '../models/user': {
    findOne: this.findOneSpy
  },
  './base-controller': {
    respondWith200: this.respondWith200Spy,
    respondWith400: this.respondWith400Spy,
    respondWith404: this.respondWith404Spy
  }
});

這是我的一個測試看起來像:

it('should return 200 with user data if user email matches existing user', function() {
  // THIS FUNCTION IS NEVER HIT
  this.respondWith200Spy = function(res, data) {
    data.should.equal({id:4, email:'john@lennon.com', facebookId:12453, displayName: 'John Lennon'});
    done();
  };
  const req = {session:{user:{email:'john@lennon.com'}}};
  this.controller.getMe(req, this.res, this.nextSpy);
  this.findOneSpy.should.have.been.called;
});

因為我們實際上沒有將回調傳遞給函數,並且函數沒有真正返回任何東西(只是在其他地方做異步事情),我無法弄清楚如何測試它以確保它正常工作。 任何幫助表示贊賞。

實際代碼工作得很好。 我只是想在項目中進行一些高質量的單元測試。 謝謝!

我最終找到了使用proxyquire做到這一點的方法。 我剛剛重新respondWith200了我正在測試的控制器類,並使respondWith200回調作出斷言。 然后我為next調用done函數創建了一個新的間諜(傳遞給測試用例)。 我驗證了代碼都被點擊了。

it('should return 200 with user data if user email matches existing user', function(done) {
  const controller = proxyquire('../../controllers/user-controller', {
    '../models/user': {
      findOne: this.findOneSpy
    },
    './base-controller': {
      respondWith200: function(res, data) {
        data.displayName.should.equal('John Lennon');
      },
      respondWith400: this.respondWith400Spy,
      respondWith404: this.respondWith404Spy
    }
  });
  const req = {grft_session:{user:{email:'john@lennon.com'}}};
  const nextSpy = sinon.spy(function() {
    done();
  });
  controller.getMe(req, this.res, nextSpy);
  this.findOneSpy.should.have.been.called;
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM