2015-01-30 1 views
10

В файле я хотел бы проверить, у меня есть следующий код:гася в promisified функции с Синоном и Блюбердо

var httpGet = Promise.promisify(require("request").get); 
httpGet(endpoint, { 
    auth: {bearer: req.body.access_token}, 
    json: true 
}) 
    .then(...) 

Теперь, в моих тестах, я хочу, чтобы убедиться, что HttpGet называли когда-то, и убедитесь, что параметры действительны. Перед тем, как promisified мой тест не выглядел так:

beforeEach(function() { 
    request.get = sinon.stub() 
     .yields(null, null, {error: "test error", error_description: "fake google error."}); 
}); 

afterEach(function() { 
    expect(request.get).to.have.been.calledOnce(); 
    var requestArgs = request.get.args[0]; 
    var uri = requestArgs[0]; 

    expect(uri).to.equal(endpoint); 
    //... 
}); 

К сожалению, это уже не работает, когда request.GET является promisified. Вместо этого я попробовал наследовать request.getAsync (поскольку bluebird добавляет «Async» к многозначным функциям), но это тоже не работает. Есть идеи?

ответ

4

Promise.promisify не модифицирует объект, он просто берет функцию и возвращает новую функцию, она полностью не знает, что функция даже принадлежит "request".

"Async" суффиксом методы добавлены к объекту при использовании promisify Все

Promise.promisifyAll(require("request")); 

request.getAsync = sinon.stub() 
     .yields(null, null, {error: "test error", error_description: "fake google error."}); 

expect(request.getAsync).to.have.been.calledOnce(); 
+1

В случае, если кто-то еще работает в это, что работает для меня, чтобы сделать 'Promise.promisifyAll()' первый, а затем поставить заглушку на 'someMethodAsync()', который вы хотите временно переопределить для теста. – nephets

0

Любой, встретив это. У меня есть небольшая утилита FUNC

function stubCBForPromisify(stub) { 
    let cbFn = function() { 
    let args = [...arguments]; 
    args.shift(); 
    return stub(...args); 
    }; 
    return cbFn.bind(cbFn,() => ({})); 
} 

В тесте

var getStub = sinon.stub().yields(null, {error: "test error", error_description: "fake google error."}) 
sinon.stub(require("request"), 'get', stubCBForPromisify(getStub)) 
expect(getStub).to.have.been.calledOnce(); 
0

я бегу в проблемы тестирования это с помощью tape и proxyquire. Я не уверен, какие люди используют шаблоны/рамки, которые позволяли им изменять объект required 'd request, как показано в принятом ответе. В моем случае, в файле я хочу проверить I require('jsonFile'), затем позвоните bluebird.promisifyAll(jsonFile). В обычных условиях это создает метод readFileAsync, который я хочу заглушить. Однако, если во время тестирования я пытаюсь использовать proxyquire для передачи в заглушку, вызов promisifyAll перезаписывает мой заглушка.

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

core.js:

var jsonFile = require('jsonfile'); 
var Promise = require('bluebird'); 
Promise.promisifyAll(jsonFile); 

exports.getFile = function(path) { 
    // I want to stub this method during tests. It is 
    // created by promisifyAll 
    return jsonFile.readFileAsync(path); 
} 

core-test.js:

var proxyquire = require('proxyquire'); 
var tape = require('tape'); 
var sinon = require('sinon'); 
require('sinon-as-promised'); 

tape('stub readFileAsync', function(t) { 
    var core = proxyquire('./core', { 
    'jsonfile': { 
     readFileAsync: sinon.stub().resolves({}) 
    }, 
    'bluebird': { promisifyAll: function() {} } 
    }); 
    // Now core.getFile() will use my stubbed function, and it 
    // won't be overwritten by promisifyAll. 
}); 
Смежные вопросы