62 votes

Comment envoyer des données de publication brutes dans un test fonctionnel Rails?

Je souhaite envoyer des données de publication brutes (par exemple, un JSON non paramétré) à l'un de mes contrôleurs à des fins de test:

class LegacyOrderUpdateControllerTest < ActionController::TestCase
 test "sending json" do
   post :index, '{"foo":"bar", "bool":true}'
 end
end

mais cela me donne un NoMethodError: undefined method `symbolize_keys' for #<String:0x00000102cb6080>

Quelle est la manière correcte d’envoyer des données de publication brutes dans ActionController :: TestCase?

Voici quelques code de contrôleur

def index
    post_data = request.body.read
    req = JSON.parse(post_data)

57voto

bbrowning Points 432

J'ai couru à travers le même problème et trouvé une solution.

Dans votre test_helper.rb définir la méthode suivante à l'intérieur de ActiveSupport::cas de test:

  def raw_post(action, params, body)
    @request.env['RAW_POST_DATA'] = body
    response = post(action, params)
    @request.env.delete('RAW_POST_DATA')
    response
  end

Dans votre test fonctionnel, l'utiliser comme l' post méthode mais passer le raw post-corps en tant que troisième argument.

class LegacyOrderUpdateControllerTest < ActionController::TestCase
 test "sending json" do
   raw_post :index, {}, {:foo => "bar", :bool => true}.to_json
 end
end

J'ai testé cela sur les Rails 2.3.4 lors de la lecture du raw post-corps à l'aide de

request.raw_post

au lieu de

request.body.read

Si vous regardez le code source , vous verrez que raw_post juste enveloppements à la demande.corps.lire avec un chèque de ce RAW_POST_DATA dans la demande env de hachage.

20voto

Andrea Reginato Points 645

J'ai effectivement résolu les mêmes questions, tout en ajoutant une ligne avant de simuler la rspec requête post. Ce que vous faites est de remplir le "RAW_POST_DATA". J'ai essayé de le supprimer les attributs de la var sur le post :créer, mais si je le fais, il ne trouve pas l'action.

Voici ma dernière solution.

def do_create(attributs)
 demande.env['RAW_POST_DATA'] = attributs.to_json
 post :créer, attributs
fin 

Dans le contrôleur, le code que vous avez besoin de lire le JSON est quelque chose de semblable à ce

 @property = Propriété.nouveau(JSON.parse(la demande.corps.read))

10voto

Grimmo Points 575

En regardant la trace de pile d'exécution d'un test, vous pouvez acquérir plus de contrôle sur demande la préparation: ActionDispatch::Intégration::RequestHelpers.post => ActionDispatch::Intégration::Session.processus=> Rack::Test::Session.env_for

Vous pouvez passer chaîne json comme :params ET spécifiez un type de contenu "application/json". Dans d'autres cas type de contenu sera mis à "application/x-www-form-urlencoded" et votre json sera analysée correctement.

De sorte que tous vous avez besoin est de préciser "CONTENT_TYPE":

post :index, '{"foo":"bar", "bool":true}', "CONTENT_TYPE" => 'application/json'

4voto

Si vous utilisez RSpec (>= version 2.12.0) et la rédaction des specs de Requête, le module qui est inclus est - ActionDispatch::Integration::Runner. Si vous regardez le code source, vous pouvez remarquer que le post des appels de méthode processus qui accepte rack_env paramètre.

Tout cela signifie que vous pouvez simplement effectuer les opérations suivantes dans votre spec:

#spec/requests/articles_spec.rb

post '/articles', {}, {'RAW_POST_DATA' => 'something'}

Et dans le contrôleur:

#app/controllers/articles_controller.rb

def create
  puts request.body.read
end

0voto

Alex Reisner Points 10026

La méthode post attend un hachage de paires nom-valeur, vous devrez donc faire quelque chose comme ceci:

 post :index, :data => '{"foo":"bar", "bool":true}'
 

Ensuite, dans votre contrôleur, obtenez les données à analyser comme ceci:

 post_data = params[:data]
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X