The ultimate rspec cheatsheet for testing Rails APIs
Test coverage
To check your test coverage, use simplecov
.
Add it to your gemfile
then run bundle install
gem 'simplecov', require: false, group: :test
At the very top of your spec/spec_helper.rb
file, add
require 'simplecov'
SimpleCov.start
Run bundle exec rspec
as usual to see test coverage.
Setup
At the top of each test file, add
require ‘rails_helper`
Test models
Describe a model test. For example, a user model
RSpec.describe User, type: :model do
describe '# when created user is valid' do
end
end
Create a model instance example
let(:user) { User.create(name: 'test_user', email: 'test@test.com', password: 'password', password_confirmation: 'password') }
Create an it block for each test.
it 'checks for the presence of values in required fields' do
expect(user.name).to eq('test_user')
end
using the expect + eq matcher inside an it block
expect(user.password).to eq(‘password’)
using the to_not + be valid matcher
expect(user).to_not be_valid
using the to + be valid
expect(user).to be_valid
Request specs
Describe a test block
RSpec.describe 'Users', type: :request do
end
Create an it block
it 'tests that an authenticated user can create comments' do
end
Within an it block, create params and necessary headers. E.g
params = { name: 'test_user', email: 'test@test.com', password: 'password', password_confirmation: 'password' }headers = { ‘Accept’: ‘application/json’, ‘Content-Type’: ‘application/json’ }
Make a request with the params and headers. For example, a POST request
post '/api/v1/users', params: params.to_json, headers: headers
Get the response from the request and save to a variable
user = JSON.parse(response.body)
Add an authorization header to a request
headers = { ‘Accept’: ‘application/json’, ‘Content-Type’: ‘application/json’, ‘Authorization’: “Bearer #{user[‘token’]}” }
Putting it all together
it 'tests that an authenticated user can create comments' do
# create a user
params = { name: 'test_user', email: 'test@test.com', password: 'password', password_confirmation: 'password' }
headers = { 'Accept': 'application/json', 'Content-Type': 'application/json' }
post '/api/v1/users', params: params.to_json, headers: headers
user = JSON.parse(response.body)# create a ticket
ticket_params = { user_id: user['user']['user_id'], title: 'test ticket', request: 'this is a test request' }
headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': "Bearer #{user['token']}" }
post '/api/v1/tickets', params: ticket_params.to_json, headers: headers
tickets = JSON.parse(response.body)end
Request matchers
.to have_http_status
expect(response).to have_http_status(401)
.to include
expect(response.body).to include('not authorized')
length
expect(tickets['tickets'].length).to eq(2)