Skip to content

Testing

David Copeland edited this page Jun 25, 2017 · 2 revisions

Stitches will scaffold a basic "ping" endpoint as well as a test for it in spec/acceptance. That test uses rspec_api_documentation to both run a real test, and produce working documentation.

In a Stitches app, the tests that would normally be in a controller test or integration tests should be in spec/acceptance. You typically don't need to write a controller test unless your controller is doing too much stuff, which it shouldn't be.

Follow the example in the ping acceptance test. The main things you want to do in the test are:

  • Assert that the JSON format coming out is correct.
  • Assert that basic error handling is working
  • Document the features of your API

To that end, the string given to example should be short:

get "/api/orders" do
  example "List" do 
  end
end

post "/api/orders" do
  example "Create" do
  end
  example "Create (with errors)" do
  end
end

# etc.

Test Helpers

Asserting Structured Errors

If you have a response in a test, you can assert that it's using the proper error format via the have_api_error matcher:

Given this JSON:

{
  "errors": [
    {
      "code": "some_code",
      "message": "some readable message"
    },
    {
      "code": "some_other_code",
      "message": "some other readable message"
    }
    # etc.
  ]
}

To assert this in your specs:

expect(response).to have_api_error(status: 404,
                                   code: "not_found",
                                   message: "the exact error message")

# regexps also work
expect(response).to have_api_error(status: 404,
                                   code: "name_invalid",
                                   message: /can't be blank/)

Omitting status will use a default of 422, which is Rails' default for validation errors.

Asserting Timestamp Formats

You can also assert the format of timestamps with be_iso8601_utc_encoded

expect(json["created_at"]).to be_iso8601_utc_encoded

Setting Headers

In your acceptance tests, you will need to post headers. TestHeaders is a class that help deal with that (examples are in the generated tests for the pings controller)

# Create headers for a version 2 request
headers = TestHeaders.new(version: 2)
post "/api/ping", {}.to_json, headers.headers

Accessing Api Clients

The ApiClients module can be mixed into any test and provides the method api_client that will return the one api client.
This works without fixtures or factories.

Testing Tips

  • Do not test JSON serialization in a unit test. The part of your app that deals with JSON formats is the controller, and you are testing that with acceptance tests, so test the format there
  • Consider supporting Consumer-driven contracts via Pact