Модульное тестирование контроллера конечной точки с узлом и переподключением

#node.js #unit-testing #express

#node.js #модульное тестирование #экспресс

Вопрос:

Я использую rewire для тестирования своих контроллеров узлов. У меня есть следующая конечная точка, которая использует request для ПОЛУЧЕНИЯ некоторых данных.

     exports.myGetEndpoint = function(req, res) {
      return request.get({
        url: 'http://baseURL/api/myGetEndpoint',
        headers: {
          authorization: { //etc }
        },
        json: true
      })
      .then(function(data) {
        res.status(200).json(data.objects);
      });
    };
  

Я хочу проверить, что когда я вызываю get метод с контроллера, который request вызывается с правильными аргументами, но я не понимаю, как ‘заглушка’ или ‘шпион’ по запросу.

     var Promise    = require('bluebird');
    var rewire     = require('rewire');
    var controller = rewire('../../controllers/myGetEndpoint.js');

    var request = {
      get: sinon.stub()
    };

    // Use rewire to mock dependencies
    controller.__set__({
      request: request
    });

    describe('myGetEndpoint', function() {
      var json;
      var req;
      var res;

      beforeEach(function(done) {
        json = sinon.spy();
        req = { headers: {} };
        res = {
          status: sinon.stub().returns({
            json: json
          })
        };
        controller.myGetEndpoint(req, res).then(function() {
          done();
        });
      });

      it('should call the correct request arguments', function() {
        // lost
      });
    });
  

Ответ №1:

Я собираюсь немного изменить ваш исходный код, чтобы использовать только обратный вызов вместо обещания. Мне нужно изучить, как заглушить обещание с помощью sinon, но вы можете получить представление о том, как его можно протестировать с помощью простого обратного вызова:

 exports.myGetEndpoint = function(req, res) {
  return request.get({
    url: 'http://baseURL/api/myGetEndpoint',
    headers: {
      authorization: { //etc }
    },
    json: true
  }, function (error, response, body) {
    res.status(200).json(response.objects);
  });
};
  

Вы не должны вызывать контроллер в beforeEach, но вы должны вызывать его внутри тестового примера. Обычно beforeEach используется для инициализации перед тестовым примером:

 var expect = require('chai').expect;
var Promise    = require('bluebird');
var rewire     = require('rewire');
var controller = rewire('../../controllers/myGetEndpoint.js');

var request = {
  get: sinon.stub()
};

// Use rewire to mock dependencies
controller.__set__({
  request: request
});

describe('myGetEndpoint', function() {
  var status;
  var json;
  var req;
  var res;

  beforeEach(function(done) {
    json = sinon.spy();
    status = sinon.stub();
    req = { headers: {} };
    res = {
      status: status.returns({
        json: json
      })
    };
  });

  it('should call the correct response arguments', function(done) {
    var response = {objects: ['objects', 'objects']}
    request.get.yields(null, response);

    controller.myGetEndpoint(req, res);

    expect(status.calledWith(200)).to.equal(true);
    expect(json.calledWith(response.objects)).to.equal(true);
  });
});
  

PS: На самом деле я не пытался его запустить, так что, возможно, есть некоторые опечатки.