如何声明我的Ajax请求并测试Ruby on Rails功能测试的JSON输出?
Answers:
Rails内置了JSON支持:
def json_response
ActiveSupport::JSON.decode @response.body
end
无需插件
然后,您可以执行以下操作:
assert_equal "Mike", json_response['name']
如果您使用的是RSpec,则值得一看的json_spec
在较新版本的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客户端实现进行验证的最佳方法。
您可以将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
块即可在其中检查响应中是否存在键和值。提示:它在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
user = JSON.parse(@response.body, object_class: OpenStruct)
assert_equal "Mike", user.name