Спецификации запроса Rspec и Rails 5

Я начинаю новый проект, мой первый с Rails 5.1.0. У меня есть pb с моей первой спецификацией запроса.

describe 'Users', type: :request do
  it 'are created from external data' do
    json_string = File.read('path/to/test_data/user_data.json')
    params = { user: JSON.parse(json_string) }
    headers = { "CONTENT_TYPE" => "application/json" }

    expect do
      post '/api/v1/users', params.to_s, headers
    end.to change {
      User.count
    }.by(1)

    expect(response.status).to eq 200
  end
end

эта спецификация возвращает ошибку ArgumentError: wrong number of arguments (given 3, expected 1). официальная документация не говори много.

Если я уберу .to_s и отправлю хеш, например:

post '/api/v1/users', params, headers

Я получил другую ошибку:

ArgumentError: unknown keyword: user

Любая мысль?


person Ruff9    schedule 14.04.2017    source источник


Ответы (2)


Я думаю, что они недавно изменили синтаксис. Теперь он должен использовать аргументы ключевого слова. Итак, что-то вроде этого:

post '/api/v1/users', params: params, headers: headers
person Sergio Tulentsev    schedule 14.04.2017
comment
Я сам столкнулся с этой проблемой при обновлении своего приложения с Rails 4.2 до 5.1. Я думаю, что это изменение не задокументировано в Rspec, потому что оно просто делегируется помощнику Rails, но мой вопрос: есть ли оптимальный способ обновить спецификации до нового формата или использовать старый без слишком большого количества исправлений? У меня есть ›900 спецификаций, из которых ~150 не работают по этой проблеме и еще ~150 по другим причинам, и я хотел бы изменить их как можно меньше, чтобы сначала обнаружить и исправить «настоящие» проблемы. - person wiz; 04.05.2017
comment
@wiz: хороший вопрос. Я не знаю о таком способе. До сих пор я вручную менял каждое вхождение. - person Sergio Tulentsev; 04.05.2017
comment
Что бы это ни стоило, я проследил метод post до ActionDispatch::Integration::Session#process, я думаю, это то, что изменилось между Rails 4 и 5. Не могу сказать, что знаком с внутренним устройством Rails, но, возможно, в какой-то момент это изменение было задокументировано? - person wiz; 04.05.2017

Вот небольшое дополнение к ответу Серджио. Если вы переходите с Rails 4 на Rails 5, у вас есть много тестов и вы не слишком заинтересованы в их изменении — по крайней мере, пока вы не закончите обновление — я нашел способ чтобы заставить их работать со старой сигнатурой метода.

В моем spec_helper я добавил

module FixLegacyTestRequests
  def get(path, par = {}, hdr = {})
    process(:get, path, params: par, headers: hdr)
  end
  def post(path, par = {}, hdr = {})
    process(:post, path, params: par, headers: hdr)
  end
  def put(path, par = {}, hdr = {})
    process(:put, path, params: par, headers: hdr)
  end
  def delete(path, par = {}, hdr = {})
    process(:delete, path, params: par, headers: hdr)
  end
end

а затем я добавил эту конфигурацию для каждого теста:

RSpec.configure do |config|
  config.before :each do |example|
    extend(FixLegacyTestRequests) # to be removed at some point!
  end
end

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

person wiz    schedule 04.05.2017