Test your JSON in RSpec, MiniTest or Cucumber, like a boss.
The only matcher I let my kids play with -- Mom
Ever since the dawn of mankind, humans everywhere have been searching for a tool to test their JSON.
Then computers were invented.
Then matchJSON came about.
Then everyone lived happily ever after.
Stop warping your brain with hard-to-read regex and weird-looking tests.
The old, yucky way:
it "returns the current pony" do
get "/ponies/#{pony.id}"
current_pony = JSON.parse(response.body)["pony"]
expect(current_pony["cuteness"]).to eq 90
expect(current_pony["fluffiness"]).to eq "extra-fluffy"
expect(current_pony["name"]).to eq "McPony"
end
The new, cool way:
it "returns the current pony" do
get "/ponies/#{pony.id}"
expect(response).to match_json(<<-JSON)
{
"cuteness": 90,
"fluffiness": "extra-fluffy",
"name": "McPony",
}
JSON
end
Wait, you already use JSON-Schema? We're BFFs ❤️
it "returns the current pony" do
get "/ponies/#{pony.id}"
# JSON-Schema to check the schema
expect(response).to match_response_schema(:pony)
# MatchJSON to test the values (gotta love explicit tests)
expect(response).to match_json(<<-JSON)
{
"cuteness": 90,
"fluffiness": "extra-fluffy",
"name": "McPony",
}
JSON
end
- Drop this baby into your Gemfile like so:
gem 'match_json'
- Run
bundle
In spec_helper.rb or rails_helper.rb include library as following:
require 'match_json/rspec'
In minitest's test_helper.rb add this:
require 'match_json/minitest'
Add some patterns in the mix to make things interesting:
# RSpec
it 'returns ponies' do
get '/ponies/#{pony.id}'
expect(response).to match_json(<<-JSON)
{
"id": "{uuid}", # UUID Pattern
"cuteness": 90,
"fluffiness": "extra-fluffy",
"name": "McPony",
"created_at": "{date_time_iso8601}" # DateTime pattern (well, duh)
}
JSON
end
Here's a list of the built-in patterns we provide:
date_time_iso8601
date
uuid
email
string
Just add them to spec/support/match_json.rb
:
MatchJson::Matchers::IncludeJson::PATTERNS['id'] = /\A\d{6}\z/
MatchJson::Matchers::IncludeJson::PATTERNS[/id:(\w )'] = proc { |actual, match| /\A#{match}_\z/ =~ actual }
and then use it in your spec like so:
it 'uses patten to check value' do
# MatchJson::Matchers::IncludeJson::PATTERNS['id'] = /\A\d{6}\z/
expect(%Q({"one": "123456"})).to match_json(%Q({"one": "{id}"}))
# .. you can even do this:
expect(%Q({"one": 123456})).to match_json(%Q({"one": {id}}))
# MatchJson::Matchers::IncludeJson::PATTERNS[/id:(\w )'] = proc { |actual, match| /\A#{match}_\z/ =~ actual }
expect(%Q({"id": "usr_xxx"})).to match_json(%Q({"one": "{id:usr}"}))
expect(%Q({"id": "cus_xxx"})).to match_json(%Q({"one": "{id:cus}"}))
end
- Fork it ( https://github.com/[your-github-username]/match_json/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request