Comment définir les en-têtes de demande dans la spécification de demande rspec?

127

Dans les spécifications du contrôleur, je peux définir l'en-tête d'acceptation http comme ceci:

request.accept = "application/json"

mais dans la spécification de la demande, l'objet "demande" est nul. Alors, comment puis-je le faire ici?

La raison pour laquelle je veux définir l'en-tête d'acceptation http sur json est que je peux le faire:

get '/my/path'

au lieu de cela

get '/my/path.json'
Sergey
la source

Réponses:

130

Vous devriez pouvoir spécifier des en-têtes HTTP comme troisième argument de votre méthode get () comme décrit ici:

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

et ici

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

Donc, vous pouvez essayer quelque chose comme ceci:

get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}
awaage
la source
3
Nous devions utiliser 'HTTP_ACCEPT': get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}
Matt Scilipoti
58
REMARQUE: Ceci est pour les tests d'intégration, similaire au commentaire ci-dessous, dans les tests de contrôleur rspec-rails, vous utiliseriez: request.env ["HTTP_ACCEPT"] =
Alex Soto
5
Petit problème que j'ai rencontré parce que je suis stupide: les clés d'en-tête doivent être des chaînes. Les symboles n'apparaîtront pas.
ajmurmann
@ajmurmann Maintenant, les symboles fonctionnent: l'en-tête "Authorization" peut être :authorization.
Franklin Yu
13
La nouvelle syntaxe RSspec 3 serait comme get my_resource_path, params: {}, headers: { 'HTTP_ACCEPT' => "application/json" }`
Cyril Duchon-Doris
39

J'ai utilisé ceci dans Test :: Unit:

@request.env['HTTP_ACCEPT'] = "*/*, application/youtube-client"
get :index
Sytse Sijbrandij
la source
3
De même, comme Alex Soto le note dans un commentaire sur une autre réponse, dans les tests du contrôleur rspec-rails, vous pouvez utiliser: request.env ["HTTP_ACCEPT"]
gerry3
merci beaucoup mec, seul exemple qui a fonctionné pour moi sur une ancienne application 2.3 avecActionController::TestCase
ecoologic
+1 J'ai essayé d'utiliser une clé nommée Cookiedans le hachage des en-têtes (car c'est ce que mon navigateur envoie), mais cela n'a pas fonctionné. Puis je l'ai fait request.keyset j'ai vu une clé nommée HTTP_COOKIE. Utiliser cela a fonctionné. Ils devraient vraiment mieux documenter cela.
Kelvin
Ça marche vraiment! J'ai également trouvé cette réponse dans github.com/rspec/rspec-rails/issues/65
Stepan Zakharov
@Sytse Sijbrandij Personne n'a posé de question sur Test :: Unit. Question posée sur rspec.
Bryan Dimas
18

J'ajoute ceci ici, car je suis resté bloqué en essayant de le faire dans Rails 5.1.rc1

La signature de la méthode get est maintenant légèrement différente.

Vous devez spécifier les options après le chemin comme arguments de mot-clé, c'est-à-dire

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

Pour info, l'ensemble complet d'arguments de mots-clés est:

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

Jules Copeland
la source
18

Cela fonctionne pour les spécifications du contrôleur, pas pour les spécifications de demande:

request.headers["My Header"] = "something"
morgoth
la source
2
Cela a fonctionné pour moi, cela dépend de la façon dont vous récupérez les en-têtes, si vous utilisez request.headersourequest.env
Edgar Ortega
3
Remarque: Ceci concerne les tests de contrôleur, pas les tests d'intégration mentionnés dans la question.
Franklin Yu
3
ne fonctionnait pas pour les tests d'intégration. Fonctionne avec les tests de contrôleur, cependant.
Petr Gazarov
9

Je dois configurer les en-têtes séparément

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

Essayer de l'envoyer via get / delete / .... est une poubelle complète dans rails4 et me fait mal à la tête car il n'est jamais envoyé en en-tête mais en paramètre.

{"Accept" => "application/json"}
utilisateur4694178
la source
5
Cela répond-il vraiment à la question du PO? S'il s'agit d'une nouvelle question, il est préférable d'ouvrir une nouvelle question.
β.εηοιτ.βε
9

Utilisation de rspec avec Rack::Test::Methods

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

L'en-tête var apparaîtra comme X-Your-Header-Var

Marcusb
la source
Remarque: ceci est pour Test::Unit, pas pour RSpec.
Franklin Yu
son rspec indiquant
James Tan
1
Ouais. Dans rspec, cela soulève une ndefined method 'header'erreur pour moi.
Евгений Масленков
7

Avec RSpec 3, vous pouvez utiliser la syntaxe suivante

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

Comme décrit dans la documentation officielle de Rspec (le lien pointe vers la v3.7)

Cyril Duchon-Doris
la source
Doux. Exactement ce que je cherchais. Merci!
Francisco Quintero le
5

Pour envoyer les deux xhr: trueet les en-têtes, j'ai dû faire par exemple:

my_headers = { "HTTP_ACCEPT": "application/json" }
get my_path, xhr: true, headers: my_headers
Jim Stewart
la source
1
Voici le code source sur GitHub: github.com/rails/rails/blob/…
Karl Wilbur
Ne devrait pas l' headers =être my_headers =?
webaholik
Fixé. Merci @webaholik.
Jim Stewart
2

Votre question a déjà reçu une réponse, mais si vous souhaitez POSTER quelque chose dans une autre action, vous devez le faire:

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

Essayez quelque chose comme:

get :index, :format => 'json' 
gayavat
la source
Pas sûr, mais fonctionne probablement parce que les rails recherchent .format pour cet itinéraire; cela a fonctionné pour moi aussi.
Alan
2
Au cas où quelqu'un se demanderait, cela s'ajoute simplement en format=jsontant que paramètre de requête. Pas la même chose qu'un champ d'en-tête.
Kevin Carmody