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'

Run bundle exec rspec as usual to see test coverage.


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

Create a model instance example

let(:user) { User.create(name: 'test_user', email: '', password: 'password', password_confirmation: 'password') }

Create an it block for each test.

it 'checks for the presence of values in required fields' do
expect( eq('test_user')

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

Create an it block

it 'tests that an authenticated user can create comments' do

Within an it block, create params and necessary headers. E.g

params = { name: 'test_user', email: '', 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: '', 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)

Request matchers

.to have_http_status

expect(response).to have_http_status(401)

.to include

expect(response.body).to include('not authorized')


expect(tickets['tickets'].length).to eq(2)




Growth at Moni(YC W22) |

Love podcasts or audiobooks? Learn on the go with our new app.

DSA (Revision + Self Evaluation)

Essential Tools And Services For Software Developers To Increase Productivity

Write a Killer Cover Letter by Forlemu Clovis Tendongfor

GCP and Fast Ai v1: A full setup that’ll work

What is the difference between scrum and agile methodology in project management?

Announcing the BLADE Dashboard

Easy Python: Best Structure for a Tkinter Application GUI

Why I joined Electronic Arts in 2016?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Adebola Adeniran

Adebola Adeniran

Growth at Moni(YC W22) |

More from Medium

Making An External API Call Using Backend In A [React/Rails] App

Ruby On Rails — Action Mailer

Rails as an API: A Faster Way to Seed

WHAT_IS_THIS — A Ruby CLI to make your life a little easier