繁体   English   中英

如何测试来自 Ruby on Rails 功能测试的 JSON 结果?

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

如何断言我的Ajax请求并测试来自 Ruby on Rails 功能测试的 JSON 输出?

在 Rails 中 >= 5

使用ActionDispatch::TestResponse#parsed_body

例子:

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

在高达 4.x 的 Rails 中

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

例子:

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

Rails 内置了 JSON 支持:

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

不需要插件

然后你可以做这样的事情:

assert_equal "Mike", json_response['name']

如果你使用的是 RSpec, json_spec值得一看

https://github.com/collectiveidea/json_spec

同样对于简短的 JSON 响应,您可以简单地将 JSON 字符串与 @response.body 匹配。 这可以防止不得不依赖另一个 gem。

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

在较新版本的 rails 中,您可以利用parsed_body在测试中访问它,而无需任何工作。

对响应调用 parsed_body 会根据最后一个响应 MIME 类型解析响应正文。

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

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

没有一个答案提供了一种很好的可维护方式来验证 JSON 响应。 我觉得这个是最好的:

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

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

您可以编写如下模式:

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 客户端实现验证它的最佳方法。

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

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

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

如果您在控制器中生成 JSON,则在控制器功能测试中解析 JSON(如其他答案所示)。 如果您使用Jbuilderrabl或其他采用这种方法的 gem 呈现 JSON,则在视图单元测试中解析 JSON,而不是控制器功能测试。 单元测试通常执行起来更快且更容易编写——例如,您可以在内存中构建模型而不是在数据库中创建它们。

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

将 gem 添加到您的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块,您可以在其中检查存在和不存在的键和值的响应。 提示:它不会在README 中立即可见,但要检查一个值(例如,如果您的操作仅返回一个字符串数组),您可以这样做

  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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM