【问题标题】:How can I test my asynchronous code in a restify HTTP handler?如何在 restify HTTP 处理程序中测试我的异步代码?
【发布时间】:2017-02-01 14:08:17
【问题描述】:

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

由于我们实际上并没有将回调传递给函数,而且该函数并没有真正返回任何内容(只是在其他地方进行异步操作),我不知道如何测试它以确保它正常工作。任何帮助表示赞赏。

实际代码运行良好。我只是想在项目中进行一些质量单元测试。谢谢!

【问题讨论】:

    标签: node.js sequelize.js sinon chai restify


    【解决方案1】:

    我最终找到了使用proxyquire 的方法。我只是重新对我正在测试的控制器类进行了存根,并使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;
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-29
      • 2023-01-13
      • 2018-08-15
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      • 2011-08-09
      • 2021-08-04
      相关资源
      最近更新 更多