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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
73
0
37 362
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Ответ принят как подходящий

В Rails> = 5

Используйте ActionDispatch::TestResponse#parsed_body.

Пример:

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

В Rails до 4.x

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

Пример:

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

С добавлением OpenStruct вы можете печатать немного меньше: user = JSON.parse(@response.body, object_class: OpenStruct)assert_equal "Mike", user.name

Jimmy Bosse 02.10.2018 21:37

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

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

Rails имеет встроенную поддержку JSON:

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

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

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

assert_equal "Mike", json_response['name']

Для повышения производительности вам, вероятно, понадобится что-то вроде: @json_response || = ActiveSupport :: JSON.decode @ response.body

Alex Neth 05.03.2011 04:36

Алекс: Разве это не кэширует ответ первого теста и не возвращает его во всех последующих тестах JSON?

iGEL 25.03.2011 23:51

Это кэширует ответ для всех запросов в одной тестовой функции, что может быть нежелательным эффектом. Чтобы уточнить, он не будет кешировать тесты ACROSS.

WattsInABox 03.10.2011 19:25

Если вы используете RSpec, стоит взглянуть на json_spec

https://github.com/collectiveidea/json_spec

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

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

Вы можете использовать AssertJson драгоценный камень для красивого DSL, который позволяет вам проверять ключи и значения, которые должны присутствовать в вашем ответе JSON.

Добавьте драгоценный камень в свой Gemfile:

group :test do
  gem 'assert_json'
end

Это быстрый пример того, как может выглядеть ваш функциональный тест / тест контроллера (пример представляет собой адаптацию их ПРОЧТИ МЕНЯ):

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, где вы можете проверить ответ на существующие и несуществующие ключи и значения. Подсказка: это не сразу видно в ПРОЧТИ МЕНЯ, но для проверки значения (например, если ваше действие просто возвращает массив строк) вы можете сделать

  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

Очень хорошо. Я только что внес в него небольшое исправление.

gertas 26.04.2014 02:49

Я не рекомендую использовать этот ДРАГОЦЕННЫЙ КАМЕНЬ. В нем много проблем.

Zack 08.07.2014 02:11

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

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

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

В более новых версиях 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...

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

Другие вопросы по теме