Wie setze ich Anforderungsheader in der rspec-Anforderungsspezifikation?

127

In der Controller-Spezifikation kann ich den http-Accept-Header wie folgt festlegen:

request.accept = "application/json"

In der Anforderungsspezifikation ist das Objekt "request" jedoch null. Wie kann ich das hier machen?

Der Grund, warum ich den http accept-Header auf json setzen möchte, ist, dass ich dies tun kann:

get '/my/path'

an Stelle von

get '/my/path.json'
Sergey
quelle

Antworten:

130

Sie sollten in der Lage sein, HTTP-Header als drittes Argument für Ihre get () -Methode anzugeben, wie hier beschrieben:

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

und hier

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

Sie können also Folgendes ausprobieren:

get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}
warten
quelle
3
Wir mussten 'HTTP_ACCEPT' verwenden: get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}
Matt Scilipoti
58
HINWEIS: Dies ist für Integrationstests, ähnlich dem Kommentar unten, in rspec-Rails-Controller-Tests, die Sie verwenden würden: request.env ["HTTP_ACCEPT"] =
Alex Soto
5
Kleine Gotcha, auf die ich gestoßen bin, weil ich dumm bin: Die Header-Tasten müssen Strings sein. Symbole werden nicht angezeigt.
Ajmurmann
@ajmurmann Jetzt funktionieren Symbole: "Authorization" -Header kann sein :authorization.
Franklin Yu
13
New RSspec 3 Syntax wie wäre get my_resource_path, params: {}, headers: { 'HTTP_ACCEPT' => "application/json" }`
Cyril Duchon-Doris
39

Ich habe dies in Test :: Unit verwendet:

@request.env['HTTP_ACCEPT'] = "*/*, application/youtube-client"
get :index
Sytse Sijbrandij
quelle
3
In ähnlicher Weise können Sie, wie Alex Soto in einem Kommentar zu einer anderen Antwort feststellt, in rspec-Rails-Controller-Tests Folgendes verwenden: request.env ["HTTP_ACCEPT"]
gerry3
ActionController::TestCase
Vielen
+1 Ich habe versucht, einen Cookieim Header-Hash genannten Schlüssel zu verwenden (weil mein Browser dies sendet), aber es hat nicht funktioniert. Dann habe ich request.keyseinen Schlüssel namens gesehen HTTP_COOKIE. Damit hat es funktioniert. Sie sollten das wirklich besser dokumentieren.
Kelvin
Es funktioniert wirklich! Ich fand diese Antwort auch in github.com/rspec/rspec-rails/issues/65
Stepan Zakharov
@Sytse Sijbrandij Niemand fragte nach Test :: Unit. Frage zu rspec gestellt.
Bryan Dimas
18

Dies funktioniert für Controller-Spezifikationen, nicht für Anforderungsspezifikationen:

request.headers["My Header"] = "something"
Morgoth
quelle
2
Dies hat bei mir funktioniert, es hängt davon ab, wie Sie die Header abrufen, ob Sie request.headersoderrequest.env
Edgar Ortega
3
Hinweis: Dies gilt für Controller-Tests, nicht für Integrationstests, die in der Frage erwähnt werden.
Franklin Yu
3
funktionierte nicht für Integrationstests. Funktioniert jedoch mit Controller-Tests.
Petr Gazarov
17

Ich füge dies hier hinzu, da ich beim Versuch, dies in Rails 5.1.rc1 zu tun, größtenteils stecken geblieben bin

Die Signatur der get-Methode unterscheidet sich jetzt geringfügig.

Sie müssen die Optionen nach dem Pfad als Schlüsselwortargumente angeben, d. H.

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

Zu Ihrer Information, die vollständigen Schlüsselwortargumente lauten:

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

Jules Copeland
quelle
9

Ich muss Header separat einrichten

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

Der Versuch, es über get / delete / .... zu senden, ist völliger Müll in Rails4 und verursacht Kopfschmerzen, da es nie als Header, sondern als Parameter gesendet wird.

{"Accept" => "application/json"}
user4694178
quelle
5
Gibt dies wirklich eine Antwort auf die OP-Frage? Wenn es sich um eine neue Frage handelt, ist es besser, eine neue Frage zu eröffnen.
β.εηοιτ.βε
9

Verwenden von rspec mit Rack::Test::Methods

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

Der Header var wird als durchkommen X-Your-Header-Var

marcusb
quelle
Hinweis: Dies gilt Test::Unitnicht für RSpec.
Franklin Yu
seine Anzeige rspec
James Tan
1
Ja. In rspec wirft es ndefined method 'header'Fehler für mich auf.
19вгений Масленков
7

Mit RSpec 3 können Sie die folgende Syntax verwenden

get my_resource_path, params: {}, headers: { 'HTTP_ACCEPT' => "application/json" }

Wie in der offiziellen Rspec-Dokumentation beschrieben (der Link verweist auf v3.7)

Cyril Duchon-Doris
quelle
Süss. Genau das, wonach ich gesucht habe. Vielen Dank!
Francisco Quintero
5

Um beide xhr: trueund Header zu senden , musste ich zB Folgendes tun:

my_headers = { "HTTP_ACCEPT": "application/json" }
get my_path, xhr: true, headers: my_headers
Jim Stewart
quelle
1
Hier ist der Quellcode auf GitHub: github.com/rails/rails/blob/…
Karl Wilbur
Sollte nicht headers =sein my_headers =?
Webaholik
Fest. Danke @webaholik.
Jim Stewart
2

Ihre Frage wurde bereits beantwortet, aber falls Sie etwas an eine andere Aktion senden möchten, müssen Sie Folgendes tun:

post :save, {format: :json, application: {param1: "test", param2: "test"}}
Igor Escobar
quelle
2

Versuchen Sie etwas wie:

get :index, :format => 'json' 
gayavat
quelle
Nicht sicher, funktioniert aber wahrscheinlich, weil die Schienen nach .format für diese Route suchen. das hat auch bei mir funktioniert.
Alan
2
Falls sich jemand wundert, wird dies nur format=jsonals Abfrageparameter hinzugefügt. Nicht dasselbe wie ein Headerfeld.
Kevin Carmody