Как можно универсально переопределить методы get и post в RSpec? - PullRequest
2 голосов
/ 09 декабря 2011

Я бы хотел переопределить методы get и post в RSpec.

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

В целях сохранения СУХОГО состояния я попытался использовать метод config.before(:each) в spec_helper.rb, однако, похоже, что он не выполняется в той же области, что и тест, и не имеет доступа к @request .

Поэтому мой следующий самый лучший подход - переопределить get и post, которые находятся в правильной области действия.

def get *args
  @request.host = @required_domain if @required_domain
  super *args
end

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

Где я могу установить это, чтобы переопределить метод get по умолчанию?

Ответы [ 3 ]

3 голосов
/ 09 декабря 2011

однако, похоже, что он не выполняется в той же области, что и тест.

Это не совсем верно - он выполняется в той же области,но до того, как @request настроен, он не имеет никакого эффекта.

Попробуйте:

module RequestExtensions
  def get(*)
    @request.host = @required_domain if @required_domain
    super
  end
end

RSpec.configure do |c|
  c.include RequestExtensions, :type => :controller
end

HTH, David

1 голос
/ 15 мая 2016

Я только что столкнулся с проблемой, которая подтолкнула меня к этому вопросу. Принятое решение привело меня к более эффективной реализации с rack-test 0.6.3.

Я вручную создал . / Spec / helpers / rspec_http_request_override_helper.rb

module RspecHttpRequestsOverrideHelper

  def get(uri, params = {}, env = {}, &block)
    super(uri, params, set_json_headers(env), &block)
  end

  def post(uri, params = {}, env = {}, &block)
    super(uri, convert_to_json(params), set_json_headers(env), &block)
  end

  def put(uri, params = {}, env = {}, &block)
    super(uri, convert_to_json(params), set_json_headers(env), &block)
  end

  def delete(uri, params = {}, env = {}, &block)
    super(uri, convert_to_json(params), set_json_headers(env), &block)
  end

  # override other HTTP methods if necessary

  private

  def set_json_headers(env={})
    env.merge({'ACCEPT' => "application/json", 'CONTENT_TYPE' => 'application/json'}) unless env.nil?
  end

  def convert_to_json(params={})
    params.to_json unless params.nil?
  end

end

Затем я добавил ниже к моему spec_helper.rb

# require assuming project root is loaded into ruby's class paths
require './spec/helpers/rspec_http_request_override_helper'
RSpec.configure do |config|
  config.include RspecHttpRequestsOverrideHelper

  # Other settings
end

И это было все!

Примечание : Приведенный выше метод get не намеренно преобразует значение params в json. Значения параметров кодируются в строку запроса и затем отправляются. Не является частью тела HTTP в запросе, хотя метод GET http поддерживает отправку тела; подробности см. Здесь .

Моя проблема заключалась в том, что помощники по тестированию rspec для создаваемого мной API преобразовывали логические типы в строковые типы при отправке запроса в API. Оказывается, если вы не указали заголовок типа содержимого для json, данные передаются как multipart/form-data или x-www-form-urlencoded в зависимости от метода HTTP; подробности см. Здесь . Это преобразовывало мои специальные типы данных, которые действительны в json, как целые и логические значения, в строки. И фактически мне нужно преобразовать их на конце API. Только когда я добавил проверку для ввода в мой API, это было выставлено. Yay для проверок и испытаний!

Теперь мне нужно было эффективно применить заголовок типа контента ко всем моим запросам и преобразовать параметры в json при отправке запросов; Я вызывал методы http со значением params, являющимся хэшем ruby. У меня более 200 тестов, поэтому их изменение вручную не было бы оптимальным решением. Поэтому я реализовал приведенное ниже решение. Который работает очень хорошо.

Я решил придерживаться того же определения метода, что и для стоечного теста, и тогда я мог эффективно вызывать super после редактирования запросов.

Мои неудачные тесты теперь начали проходить, и мои предыдущие тесты, где ни один мудрее

Надеюсь, это поможет другим, кто сталкивается с подобной проблемой.

0 голосов
/ 14 декабря 2011

Вопрос выдает неверные предположения. Вы не должны писать спецификации контроллера в первую очередь. Все это должно быть сделано с Cucumber - и в этом случае вы можете просто указать конкретные URL-адреса, чтобы проблема исчезла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...