166 votes

Comment vérifier une réponse JSON à l'aide de RSpec ?

J'ai le code suivant dans mon contrôleur :

format.json { render :json => { 
        :flashcard  => @flashcard,
        :lesson     => @lesson,
        :success    => true
} 

Dans mon test de contrôleur RSpec, je veux vérifier qu'un certain scénario reçoit une réponse json réussie. J'ai donc ajouté la ligne suivante :

controller.should_receive(:render).with(hash_including(:success => true))

Cependant, lorsque j'exécute mes tests, j'obtiens l'erreur suivante :

Failure/Error: controller.should_receive(:render).with(hash_including(:success => false))
 (#<AnnoController:0x00000002de0560>).render(hash_including(:success=>false))
     expected: 1 time
     received: 0 times

Est-ce que je vérifie mal la réponse ?

175voto

brentmc79 Points 1367

Vous pourriez analyser le corps de la réponse comme ceci :

parsed_body = JSON.parse(response.body)

Ensuite, vous pouvez faire vos assertions sur ce contenu analysé.

parsed_body["foo"].should == "bar"

6 votes

Cela semble beaucoup plus facile. Merci.

0 votes

D'abord, merci beaucoup. Une petite correction : JSON.parse(response.body) renvoie un tableau. Cependant, ['foo'] recherche une clé dans une valeur de hachage. Le corrigé est parsed_body[0]['foo'].

5 votes

JSON.parse ne renvoie un tableau que s'il y a un tableau dans la chaîne JSON.

172voto

zetetic Points 29261

Vous pouvez examiner l'objet de réponse et vérifier qu'il contient la valeur attendue :

@expected = { 
        :flashcard  => @flashcard,
        :lesson     => @lesson,
        :success    => true
}.to_json
get :action # replace with action name / params as necessary
response.body.should == @expected

EDIT

En le changeant en un post rend les choses un peu plus difficiles. Voici une façon de le faire :

 it "responds with JSON" do
    my_model = stub_model(MyModel,:save=>true)
    MyModel.stub(:new).with({'these' => 'params'}) { my_model }
    post :create, :my_model => {'these' => 'params'}, :format => :json
    response.body.should == my_model.to_json
  end

Notez que mock_model ne répondra pas à to_json donc soit stub_model ou une instance réelle du modèle est nécessaire.

1 votes

J'ai essayé et, malheureusement, la réponse obtenue est " ". Cela pourrait-il être une erreur dans le contrôleur ?

0 votes

De plus, l'action est 'create', est-ce important que j'utilise un post au lieu d'un get ?

0 votes

Oui, vous voudriez post :create avec un hachage de paramètres valide.

46voto

lightyrs Points 911

En s'appuyant sur La réponse de Kevin Trowbridge

response.header['Content-Type'].should include 'application/json'

24 votes

Rspec-rails fournit une correspondance pour cela : expect(response.content_type).to eq("application/json")

4 votes

Vous ne pourriez pas simplement utiliser Mime::JSON au lieu de 'application/json' ?

0 votes

@FloatingRock Je pense que vous aurez besoin de Mime::JSON.to_s

33voto

acw Points 772

Il y a aussi le json_spec qui vaut le coup d'œil

https://github.com/collectiveidea/json_spec

0 votes

Cette bibliothèque comprend également des définitions d'étapes Cucumber qui s'avèrent très utiles.

7voto

Kevin Trowbridge Points 147

Vous pourriez vous pencher sur le 'Content-Type' pour vérifier qu'il est correct ?

response.header['Content-Type'].should include 'text/javascript'

1 votes

Pour render :json => object Je crois que Rails renvoie un en-tête Content-Type de 'application/json'.

1 votes

La meilleure option je pense : response.header['Content-Type'].should match /json/

0 votes

Je l'aime parce qu'il garde les choses simples et n'ajoute pas de nouvelles dépendances.

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