[英]How to test JSON result from Ruby on Rails functional tests?
使用ActionDispatch::TestResponse#parsed_body
。
例子:
user = @response.parsed_body
assert_equal "Mike", user['name']
使用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值得一看
同样对于简短的 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(如其他答案所示)。 如果您使用Jbuilder 、 rabl或其他采用这种方法的 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.