检查中间件是否从http调用中调用

时间:2019-01-25 09:56:32

标签: unit-testing express middleware sinon sinon-chai

如何测试一个自定义中间件实际上是从标准HTTP事件中调用的?

即。从以下位置调用中间件:

MyController.js

router.get('/some/endpoint', [myMiddleware()], (req, res, next) => {
    // Code to do whatever here
});

中间件本身可以定义为:

MyMiddleware.js

module.exports = () => {
    // Middleware code in here
}

我的任务是检查中间件是否在单元测试中被调用一次,但是我找不到与此相关的文档。

MyTest.test.js

it('Should return whatever from GET call', () => {
    return request(app).get('/some/endpoint')
        .expect(200)
        .expect(res => {res.body.should.deep.equal(bodyValue)});
    // How would I place code in here to check that MyMiddleware is called? 
    // ie. sinon.assert.calledOnce(MyMiddleware)
});

我曾考虑过使用Sinon的间谍,但我想不出如何挂接到中间件...我的尝试是这样的:

const mwSpy = sinon.spy(require('path to middleware file'));

sinon.assert(calledOnce(mwSpy));

1 个答案:

答案 0 :(得分:0)

通常的处理方式是将其分为两个测试,一个集成测试和一个单元测试。

  1. 当有人点击此端点时,我在router.get调用中指定的中间件会被调用吗?
  2. 我的中间件做对了吗?

第一部分基本上是测试Express API是否按照文档中的说明进行操作。那不是单元测试的目的(被标记为unit-testing),但是由于您已经在使用HTTP请求来测试端点,所以我想那也不是您想要的:您基本上是在为系统创建验证测试

尽管如此,您仍然可以在不使用HTTP的情况下测试Express路由,例如I detail in the answer to this question,它涉及如何以编程方式测试路由器(更快的测试,没有http),而不仅仅是坚持自己的能力。

因此,基本问题是:“我的任务是检查是否从我的单元测试中调用了中间件”。您似乎并不担心中间件是否在做正确的事情,只是它被调用而已,这就引起了我们应该测试中间件还是应该使用中间件测试层的问题。

在两种情况下,您都需要找到一种注入测试间谍的方法。您编写了一个可以注入间谍的小型实用程序方法:function setMiddleware(module){ middleware = module; },或者使用了诸如proxyquire之类的工具。参见this tutorial on Sinon's homepage for background

我只是这样做(在测试代码中):

it('Should return whatever from GET call', () => {
  var middlewareFake = sinon.fake();
  // I am assuming it's the actual app object you are referencing below in the request(app) line
  var app = proxyquire('../app/index.js', { './my-middleware': middlewareFake });

  //
  return request(app).get('/some/endpoint')
    .expect(200)
    .expect(res => {
      res.body.should.deep.equal(bodyValue)

      expect(middlewareFake).was.called;
    });
});