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

前端 未结 9 518
暗喜
暗喜 2021-01-29 23:35

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

相关标签:
9条回答
  • 2021-01-29 23:50

    If you are using RSpec, json_spec is worth a look

    https://github.com/collectiveidea/json_spec

    0 讨论(0)
  • 2021-01-29 23:56

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

    Add the gem to your Gemfile:

    group :test do
      gem 'assert_json'
    end
    

    This is a quick example how your functional/controller test could look like (the example is an adaption from their 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 just have to include the AssertJson module in your test and use the assert_json block where you can check the response for existent and non-existant keys and values. Hint: it's not immediately visible in the README, but to check for a value (e.g. 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
    
    0 讨论(0)
  • 2021-01-29 23:57

    As noted, you use JSON.parse to test the JSON, but where you perform that assertion depends on how you are rendering the JSON.

    If you are generating the JSON in the controller, you parse the JSON in controller functional tests (as the other answers are showing). If you are rendering JSON, with a view using Jbuilder, rabl or another gem that takes this approach, then parse the JSON in the view unit tests not the controller functional tests. Unit tests are generally faster to execute and easier to write - e.g., you can build models in-memory rather than create them in the database.

    0 讨论(0)
  • 2021-01-29 23:58

    Actually, you can use implicitly the JSON module:

    assert_equal assigns(:user).to_json, @response.body
    
    0 讨论(0)
  • 2021-01-29 23:59

    In Rails >= 5

    Use ActionDispatch::TestResponse#parsed_body.

    Example:

    user = @response.parsed_body
    assert_equal "Mike", user['name']
    

    In Rails up to 4.x

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

    Example:

    user = JSON.parse(@response.body)
    assert_equal "Mike", user['name']
    
    0 讨论(0)
  • 2021-01-29 23:59

    Also for short JSON responses you can simply match a string of the JSON to @response.body. This prevents having to rely on yet another gem.

    assert_equal '{"total_votes":1}', @response.body
    
    0 讨论(0)
提交回复
热议问题