Skip to content

Instantly share code, notes, and snippets.

@plus3x
Last active April 23, 2025 07:24
Show Gist options
  • Save plus3x/697d2228d4382f187e00dccc470a8c95 to your computer and use it in GitHub Desktop.
Save plus3x/697d2228d4382f187e00dccc470a8c95 to your computer and use it in GitHub Desktop.
RSpec - Include Json matcher
# frozen_string_literal: true
RSpec::Matchers.define :include_json do |expected|
match do |response|
values_match? expectation, actual
end
diffable
# TODO: Make more informative failure massage with difference between actual and expected
failure_message do |response|
"response body: " \
"#{JSON.pretty_generate(actual)} " \
"doesn't match with: " \
"#{JSON.pretty_generate(expectation)}"
end
description do
"response #{expected.inspect}"
end
def expectation
if expected.is_a?(Array)
expected.map(&:deep_stringify_keys)
else
expected.deep_stringify_keys
end
end
def actual
Oj.load(response.body)
rescue EncodingError
response.body
end
end
__END__
Expamples:
RSpec.descriver AnyController do
describe '#index' do
subject(:response) { get :index }
let(:expectation) do
{
# TODO: #match_array used to avoid issues with sorting and require using string keys in array
# TODO: Try to avoid using #match_array or stringify keys
list: match_array([
{ 'id': 1 },
{ 'id': 2 }
])
}
end
it { expect(response).to have_http_status(:success) & include_json(expectation) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment