2008-12-03 9 views

Répondre

75

Utilisez le JSON.parse JSON gem, qui prend une chaîne en entrée et retourne un hachage Ruby que le JSON représente.

est ici l'essentiel de base pour un test:

user = JSON.parse(@response.body) 
assert_equal "Mike", user['name'] 

est ici la documentation pour la pierre précieuse: http://json.rubyforge.org/. En outre, vous pouvez jouer avec la gemme JSON dans IRB assez facilement.

+0

Nice et facile - merci :) –

3

Pour les réponses JSON courtes, vous pouvez simplement faire correspondre une chaîne de caractères JSON à @ response.body. Cela évite d'avoir à compter sur une autre gemme.

assert_equal '{"total_votes":1}', @response.body 
79

Rails a support JSON construit en:

def json_response 
    ActiveSupport::JSON.decode @response.body 
end 

Pas besoin d'un plugin

Ensuite, vous pouvez faire quelque chose comme ceci:

assert_equal "Mike", json_response['name'] 
+2

Pour des performances, vous voulez probablement quelque chose comme: @json_response || = ActiveSupport :: JSON.decode @ response.body –

+6

Alex: Ne serait-ce cache la réponse du premier tester et retourner cela dans tous les tests JSON suivants? – iGEL

+2

Cela mettra en cache la réponse pour toutes les demandes dans une fonction de test, ce qui peut ne pas être un effet souhaitable. Pour clarifier, il ne mettrait pas en cache les tests ACROSS. – WattsInABox

1

En fait, vous pouvez utiliser implicitement le module JSON:

assert_equal assigns(:user).to_json, @response.body 
-1

Vous pouvez utiliser le AssertJson gem pour une belle DSL qui vous permet de vérifier les clés et les valeurs qui devraient exister dans votre JSON réponse.

Ajouter le joyau à votre Gemfile:

group :test do 
    gem 'assert_json' 
end 

Ceci est un exemple rapide comment votre test fonctionnel/contrôleur pourrait ressembler à (l'exemple est une adaptation de leur README):

class ExampleControllerTest < ActionController::TestCase 
    include AssertJson 

    def test_my_action 
    get :my_action, :format => 'json' 
    # => @response.body= '{"key":[{"inner_key":"value1"}]}' 

    assert_json(@response.body) do 
     has 'key' do 
     has 'inner_key', 'value1' 
     end 
     has_not 'key_not_included' 
    end 
    end 

end 

Vous devez simplement inclure le module AssertJson dans votre test et utiliser le bloc assert_json où vous pouvez vérifier la réponse pour les clés et les valeurs existantes et non-existantes. Astuce: il est pas immédiatement visible dans la README, mais pour vérifier une valeur (par exemple, si votre action retourne juste un tableau de chaînes) vous pouvez faire

def test_my_action 
    get :my_action, :format => 'json' 
    # => @response.body= '["value1", "value2"]' 

    assert_json(@response.body) do 
     has 'value1' 
     has 'value2' 
     has_not 'value3' 
    end 
    end 
+0

Très bien. Je viens de contribuer petit bugfix à cela. – gertas

+1

Je recommande de ne pas utiliser ce GEM. Il y a beaucoup de problèmes. – Zack

1

Comme il est indiqué, vous utilisez JSON.parse pour tester la JSON , mais où vous effectuez cette assertion dépend de la façon dont vous affichez le JSON.

Si vous générez le JSON dans le contrôleur, analysez le JSON dans les tests fonctionnels du contrôleur (comme les autres réponses le montrent). Si vous affichez JSON, avec une vue utilisant Jbuilder, rabl ou une autre gemme qui prend cette approche, alors parse the JSON in the view unit tests pas les tests fonctionnels du contrôleur. Les tests unitaires sont généralement plus rapides à exécuter et plus faciles à écrire - par ex., vous pouvez créer des modèles en mémoire plutôt que de les créer dans la base de données.

0

Aucune des réponses ne fournit un moyen agréable de vérifier une réponse JSON. Je trouve celui-ci pour être le meilleur:

https://github.com/ruby-json-schema/json-schema

Il offre une belle mise en œuvre de la norme json schema

Vous pouvez écrire un schéma comme:

schema = { 
    "type"=>"object", 
    "required" => ["a"], 
    "properties" => { 
     "a" => { 
      "type" => "integer", 
      "default" => 42 
     }, 
     "b" => { 
      "type" => "object", 
      "properties" => { 
       "x" => { 
        "type" => "integer" 
       } 
      } 
     } 
    } 
} 

et de l'utiliser comme: JSON::Validator.validate(schema, { "a" => 5 })

Meilleure façon de le vérifier par rapport à l'implémentation de mon client Android.