代码之家  ›  专栏  ›  技术社区  ›  William Yeung

如何测试RubyonRails功能测试的JSON结果?

  •  67
  • William Yeung  · 技术社区  · 16 年前

    我怎么能断言我的 Ajax 请求并测试RubyonRails功能测试的JSON输出?

    9 回复  |  直到 16 年前
        1
  •  79
  •   Peter Mortensen icecrime    11 年前

    使用 JSON gem的json.parse,它将字符串作为输入,并返回json表示的Ruby哈希。

    以下是测试的基本要点:

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

    以下是宝石的文档: http://json.rubyforge.org/ . 此外,您还可以在 IRB 很容易。

        2
  •  83
  •   Josh    14 年前

    Rails内置了JSON支持:

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

    不需要插件

    然后你可以这样做:

    assert_equal "Mike", json_response['name']
    
        3
  •  6
  •   acw    14 年前

    如果您使用的是RSPEC, 詹森规格 值得一看

    https://github.com/collectiveidea/json_spec

        4
  •  4
  •   Eric    15 年前

    此外,对于简短的JSON响应,您可以简单地将一个JSON字符串匹配到@response.body。这就避免了不得不依赖另一块宝石。

    assert_equal '{"total_votes":1}', @response.body
    
        5
  •  1
  •   Damien    12 年前

    实际上,您可以隐式使用JSON模块:

    assert_equal assigns(:user).to_json, @response.body
    
        6
  •  1
  •   Community CDub    8 年前

    如前所述,您使用json.parse来测试JSON,但是在哪里执行该断言取决于您如何呈现JSON。

    如果要在控制器中生成JSON,则需要在控制器功能测试中解析JSON(如其他答案所示)。如果要呈现JSON,则使用 Jbuilder , rabl 或者另一个采用这种方法的宝石,然后 parse the JSON in the view unit tests 不是控制器功能测试。单元测试通常执行更快,编写更容易,例如,您可以在内存中构建模型,而不是在数据库中创建模型。

        7
  •  0
  •   Vedant Agarwala    9 年前

    这些答案都不能提供一种很好的可维护性方法来验证JSON响应。我觉得这个最好:

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

    它为标准提供了一个很好的实现 json schema

    您可以编写如下模式:

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

    使用方式如下: JSON::Validator.validate(schema, { "a" => 5 })

    根据我的Android客户端实现验证它的最佳方法。

        8
  •  0
  •   Mark G.    6 年前

    在较新版本的Rails中,您可以利用 parsed_body 在没有任何工作的情况下在您的测试中访问这个。

    对响应调用parsed_body将根据上一个响应mime类型解析响应体。

    开箱即用,只支持:json。但是对于您注册的任何自定义MIME类型,您可以添加自己的编码器…

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

        9
  •  -1
  •   rkallensee    11 年前

    你可以使用 AssertJson gem 对于一个不错的DSL,它允许您检查JSON响应中应该存在的键和值。

    把宝石加到你的 Gemfile :

    group :test do
      gem 'assert_json'
    end
    

    这是一个很快的例子,你的功能/控制器测试看起来是怎样的(这个例子是从他们的 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
    

    你只需要包括 AssertJson 测试中的模块并使用 assert_json 块,您可以在其中检查响应是否存在和不存在的键和值。提示:在 自述文件 ,但要检查值(例如,如果操作只返回字符串数组),可以执行以下操作

      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