Como definir cabeçalhos de solicitação na especificação de solicitação rspec?

127

Na especificação do controlador, posso definir o cabeçalho http accept como este:

request.accept = "application/json"

mas na especificação da solicitação, o objeto "request" é nulo. Então, como posso fazer isso aqui?

O motivo pelo qual desejo definir o cabeçalho http accept como json é para que eu possa fazer isso:

get '/my/path'

em vez disso

get '/my/path.json'
Sergey
fonte

Respostas:

130

Você deve poder especificar cabeçalhos HTTP como o terceiro argumento para o método get (), conforme descrito aqui:

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

e aqui

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

Então, você pode tentar algo como isto:

get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}
aguardar
fonte
3
Nós precisávamos usar 'HTTP_ACCEPT': get '/my/path', nil, {'HTTP_ACCEPT' => "application/json"}
Matt Scilipoti
58
NOTA: Isto é para teste de integração, semelhante ao comentário abaixo, nos testes do controlador rspec-rails, você usaria: request.env ["HTTP_ACCEPT"] =
Alex Soto
5
Peguei uma pegadinha pequena porque sou boba: as chaves do cabeçalho devem ser Strings. Os símbolos não aparecerão.
ajmurmann
@ajmurmann Agora os símbolos funcionam: o cabeçalho "Autorização" pode ser :authorization.
Franklin Yu
13
A nova sintaxe do RSspec 3 seria como get my_resource_path, params: {}, headers: { 'HTTP_ACCEPT' => "application/json" }`
Cyril Duchon-Doris
39

Eu usei isso em Test :: Unit:

@request.env['HTTP_ACCEPT'] = "*/*, application/youtube-client"
get :index
Sytse Sijbrandij
fonte
3
Da mesma forma, como observa Alex Soto em um comentário sobre uma outra resposta, em rspec-rails testes controlador, você pode usar: request.env [ "HTTP_ACCEPT"]
gerry3
graças um cara muito, único exemplo que funcionou para mim em um velho 2.3 aplicativo comActionController::TestCase
ecoologic
+1 Tentei usar uma chave nomeada Cookieno hash dos cabeçalhos (porque é isso que meu navegador envia), mas não funcionou. Então eu fiz request.keyse vi uma chave chamada HTTP_COOKIE. Usando isso funcionou. Eles realmente devem documentar isso melhor.
Kelvin
Realmente funciona! Também encontrei essa resposta em github.com/rspec/rspec-rails/issues/65
Stepan Zakharov
@Sytse Sijbrandij Ninguém perguntou sobre o Test :: Unit. Pergunta feita sobre rspec.
Bryan Dimas
18

Estou adicionando isso aqui, pois fiquei muito preso tentando fazer isso no Rails 5.1.rc1

A assinatura do método get é um pouco diferente agora.

Você precisa especificar as opções após o caminho como argumentos de palavra-chave, ou seja,

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

Para sua informação, o conjunto completo de argumentos de palavras-chave é:

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

Jules Copeland
fonte
18

Isso está funcionando para especificações do controlador, não para solicitar especificações:

request.headers["My Header"] = "something"
Morgoth
fonte
2
Isso funcionou para mim, isso depende de como você está recuperando os cabeçalhos, se você estiver usando request.headersourequest.env
Edgar Ortega
3
Nota: Isso é para testes do controlador, não para testes de integração mencionados na pergunta.
Franklin Yu
3
não funcionou para testes de integração. Funciona com testes de controlador, no entanto.
Petr Gazarov 23/03
9

Eu tenho que configurar cabeçalhos separadamente

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

Tentar enviá-lo via get / delete / .... é um lixo completo no rails4 e está causando dor na minha cabeça porque nunca é enviado como cabeçalho, mas como parâmetro.

{"Accept" => "application/json"}
user4694178
fonte
5
Isso realmente fornece uma resposta para a pergunta do OP? Se for uma nova pergunta, é melhor abrir uma nova pergunta.
β.εηοιτ.βε
9

Usando rspec com Rack::Test::Methods

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

O cabeçalho var será exibido como X-Your-Header-Var

marcusb
fonte
Nota: isto é para Test::Unit, não para RSpec.
Franklin Yu
sua rspec indicando
James Tan
1
Sim. No rspec, gera ndefined method 'header'erro para mim.
Евгений Масленков
7

Com o RSpec 3, você pode usar a seguinte sintaxe

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

Conforme descrito na documentação oficial do Rspec (o link aponta para a versão 3.7)

Cyril Duchon-Doris
fonte
Doce. É mesmo o que eu procurava. Obrigado!
Francisco Quintero
5

Para enviar ambos xhr: truee cabeçalhos, tive que fazer, por exemplo:

my_headers = { "HTTP_ACCEPT": "application/json" }
get my_path, xhr: true, headers: my_headers
Jim Stewart
fonte
1
Aqui está o código fonte no GitHub: github.com/rails/rails/blob/...
Karl Wilbur
Não deveria headers =ser my_headers =?
Webaholik
Fixo. Obrigado @webaholik.
21418 Jim Stewart
2

Sua pergunta já foi respondida, mas caso você queira postar algo para outra ação, você deve fazer o seguinte:

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

Tente algo como:

get :index, :format => 'json' 
gayavat
fonte
Não tenho certeza, mas provavelmente funciona porque os trilhos estão procurando .format para essa rota; isso também funcionou para mim.
Alan
2
Caso alguém esteja se perguntando, isso apenas adiciona format=jsoncomo um parâmetro de consulta. Não é o mesmo que um campo de cabeçalho.
precisa