Как установить заголовки запроса в спецификации запроса rspec?


127

В спецификации контроллера я могу установить заголовок принятия http следующим образом:

request.accept = "application/json"

но в спецификации запроса объект «запрос» равен нулю. Так как я могу это сделать здесь?

Причина, по которой я хочу установить заголовок http accept в json, заключается в том, что я могу сделать это:

get '/my/path'

вместо этого

get '/my/path.json'

Ответы:


130

Вы должны иметь возможность указать HTTP-заголовки в качестве третьего аргумента вашего метода get (), как описано здесь:

http://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html#method-i-get

и тут

http://api.rubyonrails.org/classes/ActionDispatch/Integration/Session.html#method-i-process

Итак, вы можете попробовать что-то вроде этого:

get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}

3
Нам нужно было использовать HTTP_ACCEPT: get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}
Мэтт Скилипоти,

58
ПРИМЕЧАНИЕ. Это для интеграционного тестирования, аналогично комментарию ниже, в тестах контроллера rspec-rails вы должны использовать: request.env ["HTTP_ACCEPT"] =
Alex Soto

5
Небольшая ошибка, с которой я столкнулся из-за своей глупости: ключи заголовка должны быть строками. Символы не появятся.
аймурманн

@ajmurmann Теперь символы работают: заголовок "Авторизация" можно :authorization .
Франклин Ю,

13
Новый синтаксис RSspec 3 будет иметь вид get my_resource_path, params: {}, headers: { 'HTTP_ACCEPT' => "application/json" }`
Сирил Дюшон-Дорис

39

Я использовал это в Test :: Unit:

@request.env['HTTP_ACCEPT'] = "*/*, application/youtube-client"
get :index

3
Точно так же, как отмечает Алекс Сото в комментарии к другому ответу, в тестах контроллеров rspec-rails вы можете использовать: request.env ["HTTP_ACCEPT"]
gerry3

ActionController::TestCase
Большое

+1 Я пробовал использовать ключ, указанный Cookieв хэше заголовков (потому что это то, что отправляет мой браузер), но это не сработало. Потом я сделал request.keysи увидел ключ с названием HTTP_COOKIE. Использование этого сработало. Они действительно должны лучше документировать это.
Кельвин

Это действительно работает! Я также нашел этот ответ в github.com/rspec/rspec-rails/issues/65
Степан Захаров,

@Sytse Sijbrandij Никто не спрашивал о Test :: Unit. Вопрос задан по поводу rspec.
Брайан Димас

19

Это работает для спецификаций контроллера, а не для спецификаций запроса:

request.headers["My Header"] = "something"

2
Это сработало для меня, это зависит от того, как вы извлекаете заголовки, используете ли вы request.headersилиrequest.env
Эдгар Ортега

3
Примечание: это для тестов контроллера, а не для интеграционных тестов, упомянутых в вопросе.
Франклин Ю

3
не работал для интеграционных тестов. Однако работает с тестами контроллера.
Петр Газаров

18

Я добавляю это здесь, так как я сильно застрял, пытаясь сделать это в Rails 5.1.rc1

Сигнатура метода get теперь немного изменилась.

Вам необходимо указать параметры после пути в качестве аргументов ключевого слова, т.е.

get /some/path, headers: {'ACCEPT' => 'application/json'}

К вашему сведению, полный набор аргументов ключевых слов:

params: {}, headers: {}, env: {}, xhr: false, as: :symbol


9

Мне нужно настроить заголовки отдельно

request.headers["Accept"] = "application/json"

Попытка отправить его через get / delete / .... - это полный мусор в rails4 и вызывает боль в моей голове, потому что он никогда не отправляется как заголовок, а как параметр.

{"Accept" => "application/json"}

5
Действительно ли это дает ответ на вопрос OP? Если это новый вопрос, лучше задать новый вопрос.
β.εηοιτ.βε

9

Использование rspec с Rack::Test::Methods

header 'X_YOUR_HEADER_VAR', 'val'
get '/path'

Заголовок var будет выглядеть как X-Your-Header-Var


Примечание: это Test::Unitдля RSpec, а не для него.
Франклин Ю

его указывающий rspec
Джеймс Тан

1
Да. В rspec это вызывает ndefined method 'header'у меня ошибку.
Евгений Масленков


5

Чтобы отправить оба xhr: trueзаголовка и заголовки, мне пришлось сделать, например:

my_headers = { "HTTP_ACCEPT": "application/json" }
get my_path, xhr: true, headers: my_headers

1
Вот исходный код на GitHub: github.com/rails/rails/blob/…
Карл Уилбур

Не должно headers =быть my_headers =?
webaholik

Исправлена. Спасибо @webaholik.
Джим Стюарт

2

На ваш вопрос уже был дан ответ, но если вы хотите отправить что-то в другое действие, вы должны сделать это:

post :save, {format: :json, application: {param1: "test", param2: "test"}}

2

Попробуйте что-нибудь вроде:

get :index, :format => 'json' 

Не уверен, но, вероятно, работает, потому что rails ищет .format для этого маршрута; это сработало и для меня.
Алан

2
Если кому-то интересно, это просто добавляется format=jsonкак параметр запроса. Не то же самое, что и поле заголовка.
Кевин Кармоди,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.