简体   繁体   中英

How to test a JSON REST API

I'm brand new to ruby (first day working with ruby) so please forgive any novice questions and lack of understanding.

I'm trying to validate the responses to http callouts.

For example, let's say the endpoint is the following:

https://applicationname-api-sbox02.herokuapp.com 

And, I'm trying to authenticate a user by sending a get request like this:

get_response = RestClient.get( "https://applicationname-api-sbox02.herokuapp.com/api/v1/users", 
                    {
                        "Content-Type" => "application/json",
                        "Authorization" => "token 4d012314b7e46008f215cdb7d120cdd7",
                        "Manufacturer-Token" => "8d0693ccfe65104600e2555d5af34213"
                    }
                ) 

Now, I want to validate the response and do the following: - parse the response to ensure that it is valid JSON - do some validation and verify the JSON has the correct data (verify that id == 4 for example) - if an error is encountered, raise an exception using the 'raise' method.

In my first feeble attempt I tried the following:

puts get_response.body
if get_response.code == 200
puts "********* Get current user successful"
else
puts "Get current user failed!!"
end 

Now, this returned that getting the current user was successful, but how do I actually parse the json, verify the correct id, and raise an exception if an error occurred?

Instead of raising an exception, write a test.

A straightforward approach, using the json parser and unit test framework from the std lib:

require 'minitest/autorun'
require 'rest_client'
require 'json'

class APITest < MiniTest::Unit::TestCase
  def setup
    response = RestClient.get("https://applicationname-api-sbox02.herokuapp.com/api/v1/users", 
      {
         "Content-Type" => "application/json",
         "Authorization" => "token 4d012314b7e46008f215cdb7d120cdd7",
         "Manufacturer-Token" => "8d0693ccfe65104600e2555d5af34213"
      }
    ) 
    @data = JSON.parse response.body
  end

  def test_id_correct
    assert_equal 4, @data['id']
  end
end

Execute with ruby $filename

JSON.parse parses a JSON string into a ruby hash

Getting started with minitest

If you are using ruby 1.8, you'll need to install the json gem and either install the minitest gem , or switch to the older testunit API. If you choose the latter, then you'll need to change require 'minitest/autorun' -> require 'test/unit' and MiniTest::Unit::TestCase -> Test::Unit::TestCase

I'm a little late to the party, but I recently co-created an rspec driven framework called Airborne for just this purpose. Check it out: https://github.com/brooklynDev/airborne

here is an example from our specs so you can see how we test json api:

it 'returns charge' do
  get "/charges/#{charge.id}", '', headers

  expect(response.status).to eq(200)
  expect(response).to match_response_schema(:charge)
  expect(response).to match_json(<<-JSON)
  {
    "id":"{id}",
    "email": "{email}",
    "ip": "127.0.0.1",
    "amount": 10500,
    "state": "captured",
    "captured_amount": 10500,
  }
  JSON
end

Lets look at it closely

  1. match_response_schema(:charge)

This matcher checks that json we get in response is in general valid. We use json-schema (json schema validator) for it. Guys from Thoughtbot have a detailed guide how to use json schema validator and create own matcher in this blog post.

Understanding JSON Schema is where I got a lot of useful information on how to create schemas for JSON documents.

  1. match_json

This is our own matcher and we have released match_json gem recently. Using it you can test structure and values of your json. Here are two great features of this matcher:

  • if you don't know exact values, you can use patterns like {id}, {uuid} {date_time}, etc. we have predefined patterns but you can add your own too.
  • you get clear failure message what is wrong with your json eg "5" was not found in " > array":[1,2,3]

Parsing json can be done with the json gem: http://flori.github.com/json/

Parsed json is accessed through key/value just like in javascript. You can easily verify the values and conditionally raise errors.

Raising errors is done like so:

raise "the ID was #{id} instead of 4"

And writing unit tests can be done with Test::Unit - http://www.ruby-doc.org/stdlib-1.9.3/libdoc/test/unit/rdoc/Test/Unit.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM