【问题标题】:Unit testing express routers单元测试快速路由器
【发布时间】:2015-04-01 05:50:28
【问题描述】:

我知道这已经讨论过几次了。无论如何,我觉得所有提供的解决方案都不(完全)符合我的要求。我有以下代码:

router.js:
------------------
var Router = function(app, resourceName, controller) {
    //Create
    app.post('/api/' + resourceName, function(req, res) {
        console.log('Incoming request: ' + resourceName + ' (POST)');
        controller.create(req, res);
    });
};

module.exports = Router;

如您所见,这是一个非常“通用”的路由器。例如,它可以像这样在服务器中实例化:

var app = express();
var userController = ...
var userRouter = new Router(app, 'Users', userController);

所以我不必为每个资源编写一个文件,但我只有一个通用路由器。

我想测试我的通用路由器,但我发现了一些问题:

  1. 如何“注入”应用程序?我可以创建一个 Express (var app = express();) 的实例,但我认为模拟会更好(因为这是一个单元测试,而不是集成测试!)。获得合适的模拟的最佳方式是什么?
  2. 我究竟应该测试什么?据我所知,我的路由器本身(没有集成)除了控制台输出(不值得测试)和函数调用(controller.create(req, res);)之外没有做任何其他事情。我应该如何测试这个函数是否被调用?或者还有什么要测试的?

【问题讨论】:

    标签: node.js unit-testing express mocha.js


    【解决方案1】:
    1. 您可能应该创建一个应用程序的存根实现。

    2. 你要测试的是构造函数在指定路由+HTTP方法上注册监听器。我建议将 Sinon.js 存根放入您的应用存根中,然后在您的测试中检查它们是否使用预期的参数调用。

    【讨论】:

      【解决方案2】:
      1. 我会使用 jasmine.createSpyObj 来模拟应用程序(也可能是控制器)。
      2. 我认为您只需要测试 app.post 是否使用参数 '/api/' + resourceName 和 controller.create 进行调用,因为您没有测试 express.post 是否正常工作。

      以下是我具体如何做这两件事。

      我会稍微修改 router.js 以使其更容易:

      var Router = function(app, resourceName, controller) {
        app.post('/api/' + resourceName, controller.create.bind(controller))
      }
      
      module.exports = Router;
      

      然后测试将如下所示:

      describe("Router", function() {
        it("should route /api to controller.create", function() {
          router = require('./router');
          app = jasmine.createSpyObj('application', ['post']);
          controller = jasmine.createSpyObj('controller', ['create']);
          router(app, 'foo', controller);
          expect(app.post).toHaveBeenCalledWith('/api/foo', jasmine.any(Function));
        });
      });
      

      这不是一个完美的测试,因为它实际上并没有检查 controller.create 是否被调用。由于 .bind() 的东西,这变得有点复杂。

      describe("Router", function() {
        it("should route /api to controller.create", function() {
          router = require('./router');
          app = jasmine.createSpyObj('application', ['post']);
          controller = jasmine.createSpyObj('controller', ['create']);
          controller.create = jasmine.createSpyObj('binder', ['bind']);
          controller.create.bind.and.returnValue('bar');
          router(app, 'foo', controller);
          expect(controller.create.bind).toHaveBeenCalledWith(controller);
          expect(app.post).toHaveBeenCalledWith('/api/foo', controller.create.bind(controller));
        });
      });
      

      【讨论】:

        猜你喜欢
        • 2016-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-11
        • 1970-01-01
        • 2022-06-23
        • 1970-01-01
        相关资源
        最近更新 更多