Подтвердить что ты не робот

Как unit test выразить маршруты маршрутизатора

Я новичок в Node и Express, и я пытаюсь unit test мои маршруты/контроллеры. Я отделил свои маршруты от своих контроллеров. Как мне пройти тестирование моих маршрутов?

конфигурации /express.js

  var app = express();
  // middleware, etc
  var router = require('../app/router')(app);

приложение/маршрутизатор/index.js

  module.exports = function(app) {
    app.use('/api/books', require('./routes/books'));
  };

приложение/маршрутизатор/маршруты/books.js

  var controller = require('../../api/controllers/books');
  var express = require('express');
  var router = express.Router();

  router.get('/', controller.index);

  module.exports = router;

приложение/API/контроллеры/books.js

// this is just an example controller
exports.index = function(req, res) {
    return res.status(200).json('ok');
};

приложение/тесты/API/маршруты/books.test.js

  var chai = require('chai');
  var should = chai.should();
  var sinon = require('sinon');

  describe('BookRoute', function() {

  });
4b9b3361

Ответ 1

код:

конфигурации /express.js

var app = express();
// middleware, etc
var router = require('../app/router')(app);

module.exports = app;

приложение/тесты/API/маршруты/books.test.js

var chai = require('chai');
var should = chai.should();
var sinon = require('sinon');
var request = require('supertest');
var app = require('config/express');

describe('BookRoute', function() {
    request(app)
        .get('/api/books')
        .expect('Content-Type', /json/)
        .expect('Content-Length', '4')
        .expect(200, "ok")
        .end(function(err, res){
           if (err) throw err;
        });
});

Вопросы:

Если вашему серверу требуется начальное состояние в начале набора тестов (потому что вы выполняете вызовы, которые мутируют состояние сервера), вам нужно написать функцию, которая вернет только что настроенное приложение и начало каждой группе тестов. Существует библиотека NPM: https://github.com/bahmutov/really-need, которая позволит вам потребовать только что обновленную версию вашего сервера.

Ответ 2

Я нашел этот блог невероятно проницательным при тестировании своих собственных конечных серверов.

В блоге он адресует:

  • Как использовать библиотеку тестирования конечных точек supertest.

  • Как программно разворачивать и сбрасывать экспресс-сервер с помощью необходимых маршрутов до и после каждого теста конечной точки. (он также объясняет, почему вы хотели бы это сделать).

  • Как избежать общей ошибки, требуйте кэширования ваших модулей, необходимых в ваших модульных тестах, что приведет к непредвиденным последствиям.

Надеюсь, это поможет. Удачи, и если у вас есть дополнительные вопросы, дайте мне знать.

Ответ 3

Это интересно, потому что вы отключили свои контроллеры от своих маршрутизаторов. Другая статья StackOverflow, упомянутая в комментариях, является хорошим способом протестировать ваши контроллеры, я думаю. То, что нужно помнить с модульными тестами, - это то, что вы точно тестируете. Вам не нужно писать тесты для тестирования экспресс-библиотеки, потому что, по-видимому, у нее есть свои собственные модульные тесты. Поэтому вам просто нужно проверить свои звонки в библиотеку. Итак, для маршрута книг вам просто нужно проверить эту строку кода:

router.get('/', controller.index);

Я осмотрелся, чтобы узнать, есть ли очевидный способ получить список маршрутов из экспресс-библиотеки, но я его не видел. Возможно, вы можете просто взглянуть на библиотеку и проверить ее внутренности, чтобы убедиться, что вы правильно настроили маршрут. Другой вариант, однако, состоит в том, чтобы высмеять его и просто проверить, правильно ли вы его вызываете.

Это будет довольно сложно, потому что вам нужно макетировать некоторые фундаментальные части Javascript, чтобы протестировать эту одну строку кода. Вот как я это сделал:

describe('BookRoute', function() {
  it("should route / to books controller index", function() {
    var controller = require('../../../api/controllers/books');
    var orig_this = this;
    var orig_load = require('module')._load;
    var router = jasmine.createSpyObj('Router', ['get']);
    var express = jasmine.createSpyObj('express', ['Router']);
    express.Router.and.returnValues(router);
    spyOn(require('module'), '_load').and.callFake(function() {
      if (arguments[0] == 'express') {
        return express;
      } else {
        return orig_load.apply(orig_this, arguments);
      }
    });
    require("../../../router/routes/books");
    expect(router.get).toHaveBeenCalledWith('/', controller.index);
  });
});

Что происходит здесь, я использовал функцию Jasmine spyOn для spyOn функции _load в module.js, которая является тем, что обрабатывает все требуемые вызовы. Это так, что, когда нам нужен роутер книг и требует его ( "экспресс" ), мы можем вернуть наш экспресс SpyObj, который мы создали с помощью jasmine.createSpyObj. После того, как мы заменили express нашим объектом-шпионом, мы можем вернуть его Router SpyObj, который позволит нам шпионить за router.get. Затем мы можем проверить, чтобы он был вызван с помощью '/' и controller.index.

Возможно, это может быть сделано в какую-то утилиту, если вы хотите использовать это много.

Я обычно избегаю многого этого, используя более объектно-ориентированный подход, и либо я обхожу вокруг какого-то объекта во всем мире, что я могу издеваться над тестами, или вы можете использовать какую-то инъекцию зависимости, например, Angular.