Last active
July 31, 2024 17:35
-
-
Save kluzny/65cf70e65352ab1c18f212c7d3e626d1 to your computer and use it in GitHub Desktop.
Some custom rspec matchers for inspecting json responses
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec/expectations' | |
# expect(response).to be_json_success | |
RSpec::Matchers.define :be_json_success do |_expected| | |
match do |actual| | |
actual.status == 200 && actual.content_type.match("application/json") | |
end | |
failure_message do |actual| | |
"expected status: 200, content_type: 'application/json', got status: #{actual.status}, content_type: '#{actual.content_type}'" | |
end | |
end | |
# expect(response).to have_json_status(:created) | |
RSpec::Matchers.define :have_json_status do |expected| | |
def numeric_status(status) | |
case status | |
when Symbol | |
Rack::Utils::SYMBOL_TO_STATUS_CODE[status] | |
else | |
status | |
end | |
end | |
match do |actual| | |
actual.status == numeric_status(expected) && actual.content_type.match("application/json") | |
end | |
failure_message do |actual| | |
"expected status: #{numeric_status(expected)}, content_type: 'application/json', got status: #{actual.status}, content_type: '#{actual.content_type}'" | |
end | |
end | |
# expect(response).to have_json_keys(%w[id created_at updated_at]) | |
RSpec::Matchers.define :have_json_keys do |expected| | |
def parse(response) | |
JSON.parse(response.body) | |
end | |
def formatter(array) | |
"[ #{array.sort.join(', ')} ]" | |
end | |
# if key order is important I recommend an explicit test | |
match do |actual| | |
parse(actual).keys.sort == expected.sort | |
end | |
failure_message do |actual| | |
actual_keys = parse(actual).keys | |
difference = actual_keys.union(expected) - actual_keys.intersection(expected) | |
<<~MESSAGE | |
expected the following JSON keys: | |
#{formatter(expected)} | |
got: | |
#{formatter(actual_keys)}" | |
symmetric difference: | |
#{formatter(difference)} | |
MESSAGE | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment