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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/336716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:49:03  来源:igfitidea点击:

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

ruby-on-railsjsontdd

提问by William Yeung

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

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

回答by Josh

Rails has JSON support built in:

Rails 内置了 JSON 支持:

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

No need for a plugin

不需要插件

Then you can do something like this:

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

assert_equal "Mike", json_response['name']

回答by nicholaides

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

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

Here's the basic gist for a test:

以下是测试的基本要点:

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

Here's documentation for the gem: http://json.rubyforge.org/. Also, you can play with the JSON gem in IRBpretty easily.

这是 gem 的文档:http: //json.rubyforge.org/。此外,您可以非常轻松地在IRB 中使用 JSON gem 。

回答by acw

If you are using RSpec, json_specis worth a look

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

https://github.com/collectiveidea/json_spec

https://github.com/collectiveidea/json_spec

回答by Eric

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.

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

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

回答by Jay Mitchell

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

如前所述,您使用 JSON.parse 来测试 JSON,但在何处执行该断言取决于您如何呈现 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, rablor another gem that takes this approach, then parse the JSON in the view unit testsnot 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.

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

回答by vedant

None of the answers provides a nice maintainable way to verify a JSON response. I find this one to be the best:

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

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

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

It provides a nice implementation for the standard json schema

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

You can write a schema like:

您可以编写如下模式:

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

and use it like: JSON::Validator.validate(schema, { "a" => 5 })

并使用它: JSON::Validator.validate(schema, { "a" => 5 })

Best way to verify it against my android client implementation.

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

回答by Mark G.

In newer versions of rails, you can leverage parsed_bodyto get access to this in your tests without any work.

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

Calling parsed_body on the response parses the response body based on the last response MIME type.

Out of the box, only :json is supported. But for any custom MIME types you've registered, you can add your own encoders...

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

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

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

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

回答by Damien

Actually, you can use implicitly the JSON module:

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

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

回答by rkallensee

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

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

Add the gem to your Gemfile:

将 gem 添加到您的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):

这是一个快速示例,您的功能/控制器测试看起来如何(该示例改编自他们的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 AssertJsonmodule in your test and use the assert_jsonblock 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

您只需要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