How to check JSON result from Ruby on Rails functional tests?

How can I validate my Ajax request and test JSON output from Ruby on Rails functional tests?

+66
json ruby-on-rails tdd
Dec 03 '08 at 10:07
source share
9 answers

Use the JSON gem JSON.parse, which takes a string as input and returns the Ruby hash character that represents JSON.

Here is the main point of the test:

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

Here's the documentation for the gem: http://json.rubyforge.org/ . In addition, you can pretty easily play with the pearl of JSON in IRB .

+78
Dec 28 '08 at 6:15
source share

Rails has built-in JSON support:

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

No plugin needed

Then you can do something like this:

 assert_equal "Mike", json_response['name'] 
+83
Aug 20 '10 at 20:12
source share

If you are using RSpec, json_spec is worth a look

https://github.com/collectiveidea/json_spec

+6
Aug 01 2018-11-11T00:
source share

Also for short JSON responses, you can just map the JSON string to @ response.body. This does not allow relying on another stone.

 assert_equal '{"total_votes":1}', @response.body 
+4
Mar 20 '10 at 1:22
source share

Actually, you can use the JSON module implicitly:

 assert_equal assigns(:user).to_json, @response.body 
+1
Jul 12 '13 at 18:19
source share

As already noted, you use JSON.parse to test JSON, but where you execute this statement depends on how you display JSON.

If you create JSON in the controller, you parse JSON in the functional tests of the controller (as other answers show). If you are handling JSON using Jbuilder , rabl, or another gem that uses this approach, then parse the JSON in the view block tests , not the controller functional tests. Unit tests tend to be faster and easier to write β€” for example, you can create models in memory rather than create them in a database.

+1
Sep 06 '14 at 18:34
source share

None of the answers provide a good supported way to validate a JSON response. I believe this is the best:

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

It provides a good implementation of the standard json schema

You can write a diagram, for example:

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

and use it like: JSON::Validator.validate(schema, { "a" => 5 })

The best way to test it against my Android client implementation.

0
Apr 26 '16 at 7:03
source share

In newer versions of rails, you can use parsed_body to access this in your tests without any work.

The parsed_body call for the response analyzes the response body based on the MIME type of the last response.

Out of the box only: json is supported. But for any custom MIME types you register, you can add your own encoders ...

https://api.rubyonrails.org/v5.2.1/classes/ActionDispatch/IntegrationTest.html

0
Dec 12 '18 at 22:41
source share

You can use the AssertJson gem for a nice DSL that allows you to check the keys and values ​​that should exist in your JSON response.

Add the gem to your Gemfile :

 group :test do gem 'assert_json' end 

This is a quick example of what your functional / controller test might look like (an example is an adaptation from 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 

You need to include the AssertJson module in your test and use the assert_json block, where you can check the response to existing and nonexistent keys and values. Hint: it is not immediately visible in README , but to check the value (for example, if your action just returns an array of strings), you can do

  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 
-one
Jan 14 '14 at 15:17
source share



All Articles