2016-12-02 5 views
0

Я пишу тесты модуля контроллера для приложения Node Express.Метод экземпляра класса Stub для возврата разрешенных обещаний (с использованием Sinon)

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

Контроллер:

const Model = require('../../models/model'); 

module.exports = function (req, res, next) { 
    const instance = new Model(req.body); 

    instance.method() 
     .then(result => { 
      // do something with result 
     }) 
     .catch(err => next(err)); 
}; 

Тест:

const proxyquire = require('proxyquire'); 
const sinon = require('sinon'); 
require('sinon-as-promised'); 

const Model = require('../../../../server/models/model'); 

const stubs = { 
    model: sinon.stub(Model.prototype, 'method', function() { sinon.stub().resolves('foobar') }) 
}; 

const subject = proxyquire('../../../../server/controllers/models/method', { 
    '../../models/model': stubs.model 
}); 

Sinon.JS Documentation Заглушка API говорит:

var stub = sinon.stub(object, "method", func);

Replaces object.method with a func, wrapped in a spy.

Но я получаю эту ошибку, когда тестовый код попадает .then в контроллере:

instance.method(...).then is not a function

Calling .resolves() (от sinon-as-promised) непосредственно на окурок дает then/catch/finally методы к экземпляру класса , а не к классу метод экземпляра в соответствии с требованиями:

sinon.stub(Model.prototype, 'method').resolves('foobar')

Т заблаговременно за помощь!

ответ

0

обнаружил это решение, в котором вы сделаете свой собственные поддельным Модель:

const proxyquire = require('proxyquire'); 
const sinon = require('sinon'); 
require('sinon-as-promised'); 

const methodStub = sinon.stub().resolves('foobar'); 

const ModelStub = function() { 
    this.method = methodStub; 
}; 

const subject = proxyquire('../../../../server/controllers/models/method', { 
    '../../models/model': ModelStub 
}); 

Кредит составляет Darren Hurley.

1

Вам необходимо вернуть sinon.stub().resolves('foobar') из вашей функции заглушки.

const stubs = { 
    model: sinon.stub(Model.prototype, 'method', 
    function() { return sinon.stub().resolves('foobar') }) 
}; 

Но вы, вероятно, просто будете лучше возвращать родное обещание, так как вы не сохраняя ссылку на внутреннюю заглушку:

const stubs = { 
    model: sinon.stub(Model.prototype, 'method', 
    function() { return Promise.resolve('foobar') }) 
}; 
+1

Спасибо, но извините - первое предложение по-прежнему возвращает 'TypeError: instance.method (...), а затем не является функцией', а вторая возвращает 'TypeError: instance.method не является функцией'. –

+0

Пользуется тем, что второе из ваших решений работает для stubbing [статические методы] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static) (в отличие от методы, вызываемые на экземплярах класса, о которых я спрашивал) - спасибо! –