Testing Your API
Testing is a critical part of building robust APIs. Since Grape applications are Rack-based, you can test them using tools like rack-test
.
Testing with Rack-Test
rack-test
provides a simple DSL for making requests to a Rack application and inspecting the response.
RSpec Example
Here’s how you can test a Grape API with RSpec and rack-test
.
# spec/api/twitter_api_spec.rb
require 'spec_helper'
describe Twitter::API do
include Rack::Test::Methods
def app
Twitter::API
end
context 'GET /api/statuses/public_timeline' do
it 'returns an empty array of statuses' do
get '/api/statuses/public_timeline'
expect(last_response.status).to eq(200)
expect(JSON.parse(last_response.body)).to eq []
end
end
context 'GET /api/statuses/:id' do
it 'returns a status by id' do
status = Status.create!
get "/api/statuses/#{status.id}"
expect(last_response.body).to eq status.to_json
end
end
end
Minitest Example
# test/api/twitter_api_test.rb
require 'test_helper'
class TwitterAPITest < Minitest::Test
include Rack::Test::Methods
def app
Twitter::API
end
def test_public_timeline_returns_empty_array
get '/api/statuses/public_timeline'
assert last_response.ok?
assert_equal [], JSON.parse(last_response.body)
end
end
Testing with Rails
If your Grape API is mounted within a Rails application, you can use Rails's built-in testing tools.
RSpec with Rails
When using RSpec in a Rails project, request specs are the ideal place to test your API.
# spec/requests/twitter_api_spec.rb
require 'rails_helper'
describe Twitter::API, type: :request do
context 'GET /api/statuses/public_timeline' do
it 'returns an empty array of statuses' do
get '/api/statuses/public_timeline'
expect(response.status).to eq(200)
expect(JSON.parse(response.body)).to eq []
end
end
end
Stubbing Helpers
Testing endpoints that rely on helper methods (like current_user
) can be tricky. Grape provides the Grape::Endpoint.before_each
hook to allow stubbing these methods before each request.
describe 'an endpoint that needs helpers stubbed' do
include Rack::Test::Methods
def app
MyAPI
end
before do
Grape::Endpoint.before_each do |endpoint|
# Allow the endpoint instance to receive the helper call
allow(endpoint).to receive(:current_user).and_return(double('user'))
end
end
after do
# Important: clean up the hook after the test
Grape::Endpoint.before_each nil
end
it 'stubs the helper and returns a successful response' do
get '/protected_resource'
expect(last_response.status).to eq(200)
end
end