Как проверить результат JSON от функциональных тестов Ruby on Rails?

Как я могу подтвердить свой запрос Ajax и протестировать вывод JSON из функциональных тестов Ruby on Rails?

Ответ 1

Используйте JSON gem JSON.parse, который берет строку как ввод и возвращает хеш-символ Ruby, который представляет JSON.

Здесь основной смысл теста:

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

Здесь документация для драгоценного камня: http://json.rubyforge.org/. Кроме того, вы можете довольно легко играть с жемчужиной JSON в IRB.

Ответ 2

У Rails встроена поддержка JSON:

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

Нет необходимости в плагине

Затем вы можете сделать что-то вроде этого:

assert_equal "Mike", json_response['name']

Ответ 4

Также для коротких ответов JSON вы можете просто сопоставить строку JSON с @response.body. Это не позволяет полагаться на еще один камень.

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

Ответ 5

Собственно, вы можете использовать модуль JSON неявно:

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

Ответ 6

Как уже отмечалось, вы используете JSON.parse для тестирования JSON, но там, где вы выполняете это утверждение, зависит от того, как вы показываете JSON.

Если вы создаете JSON в контроллере, вы разбираете JSON в функциональных тестах контроллера (как показывают другие ответы). Если вы обрабатываете JSON с помощью Jbuilder, rabl или другой драгоценный камень, который использует этот подход, затем анализировать JSON в тестах блока просмотра, а не функциональные тесты контроллера. Модульные тесты, как правило, выполняются быстрее и проще для записи - например, вы можете создавать модели в памяти, а не создавать их в базе данных.

Ответ 7

Ни один из ответов не обеспечивает хороший поддерживаемый способ проверки ответа 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.

Ответ 8

В более новых версиях rails вы можете использовать parsed_body чтобы получить доступ к этому в своих тестах без какой-либо работы.

Вызов parsed_body для ответа анализирует тело ответа на основе MIME-типа последнего ответа.

Только из коробки: поддерживается json. Но для любых пользовательских типов MIME, которые вы зарегистрировали, вы можете добавить свои собственные кодеры...

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

Ответ 9

Вы можете использовать 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