Создание заглушки запроса с синоном в мокко
Я использую mocha
для тестирования некоторых классов, и мне нужно создать заглушку библиотеки request
.
Я использую sinon
, и я могу создать заглушку метода request.get
, но я не могу создать заглушку метода request
(http-вызовы пытаются подключиться к сервер). Как я уже прочитал, request.get
является псевдонимом для request
, но когда я заглушаю request.get
, он не оказывает никакого влияния на вызовы request
.
Этот код работает (используя request.get
):
В тестах:
request = require 'request'
describe "User test", ->
user = {}
before (done) ->
user = new test.user('Ander', 18)
sinon.stub(request, 'get').yields(null, {statusCode: 200}, 'foo')
done()
after (done) ->
request.get.restore()
done()
it "testing server response", ->
user.getData().should.equal 'ander'
В источнике:
request = require 'request'
class User
contructor(@name, @age): ->
getData: ->
mydata = ''
request.get 'http://127.0.0.1:8080/', (err, response, body) ->
if not err and response.statusCode == 200
mydata = body
else
err = throw new Error "Errorea"
mydata
Но это не работает (пытается подключиться к прилагаемому URL-адресу):
В тестах:
request = require 'request'
describe "User test", ->
user = {}
before (done) ->
user = new test.user('Ander', 18)
sinon.stub(request, 'Request').yields(null, {statusCode: 200}, 'foo')
#Creating the stub this way, doesn't work neither
#sinon.stub(request, 'get').yields(null, {statusCode: 200}, 'foo')
done()
after (done) ->
request.Request.restore()
done()
it "testing server response", ->
user.getData().should.equal 'ander'
В источнике:
request = require 'request'
class User
contructor(@name, @age): ->
getData: ->
mydata = ''
request 'http://127.0.0.1:8080/', (err, response, body) ->
if not err and response.statusCode == 200
mydata = body
else
err = throw new Error "Errorea"
mydata
Каков правильный способ создания заглушки для вызова request
? Какой метод должен быть заглушен?
Ответы
Ответ 1
Хотя request
- отличная библиотека, это не хороший пример хорошо структурированного API. И поскольку модуль request
определяется как функция с дополнительными методами (аналогично express
), как я знаю, вы не можете создать заглушку для функции request
с sinon
.
Лучшее, что вы можете сделать, это не использовать функцию request
в вашем коде и использовать только request.get
, request.post
и т.д., которые вы можете легко заглушить.
Создание заглушки для request
во втором примере не помогает, потому что запрос не является методом, см. исходный код.
Ответ 2
Если кто-то все еще ищет ответ для этого, похоже, вы можете создать заглушку для запроса с помощью sinon:
before(function(done){
sinon
.stub(request, 'get')
.yields(null, null, JSON.stringify({login: "bulkan"}));
done();
});
можно найти более подробную информацию здесь
Ответ 3
Как упоминалось в одном из ответов на вопрос Как издеваться над запросом и ответом в nodejs для тестирования промежуточного программного обеспечения/контроллеров?, node - mocks-http обеспечивает способ создания запросов и ответов.
Ответ 4
Другим обходным решением будет создание заглушки с использованием модуля sinon, а зависимость запроса в соответствующем модуле может быть переопределена с помощью proxyquire.
var sinon = require('sinon');
var proxyquire = require('proxyquire');
describe('something', function(){
var request;
var overriddenModule;
before(function(){
request = sinon.stub();
// overriding the 'request' dependency with the stub
overriddenModule = proxyquire('path_to_module_using_request', {'request': request});
});
it("should do something",function(done){
// stubbing the request(options,callback) method
request.withArgs(sinon.match.any,sinon.match.any).yields(null,null,responseBody);
overriddenModule.method_which_is_doing_request;
// our logic and assertions before calling done()
});
});
Для получения дополнительной информации, проверьте эту статью об модульном тестировании с помощью Mocks в Node