Ruby on Rails has special helper methods that allow you to test instance variables in your app’s views and controllers. These are assign and assigns, which stores a hash of the instance variables you can access in your RSpec tests.
This tutorial will guide you through how to write a simple controller and view with corresponding tests. These will cover assigning instance variables depending on whether certain conditions are met.
If you want to set a controller or view’s instance variables in your RSpec test, then call assign either in a before block or at the start of an example group. The first argument is the name of the instance variable while the second is the value you want to assign to it.
before do
assign(:message, 'great test!')
end
Call its counterpart assigns to examine the instance variables that have been set.
assigns(:message) => 'great test!'
Note: According to RSpec-Rails, in Rails 5.x, controller testing has been moved to its own gem which is rails-controller-testing. Using assigns in your controller specs without adding this gem will no longer work.
Ruby on Rails RSpec includes the helper method controller to call the Controller being tested.
Here is an example of a controller action that sets an instance variable depending on parameters sent to it.
class MessageController < ApplicationController
def show
if params[:message]
@message = params[:message]
end
end
end
Then you can test this using RSpec. Divide your tests into contexts for the conditions that determine whether the assignment should happen. The first one is when the message is missing from the parameters.
context 'when params[:message] is not present' do
before { post :show }
it 'does not assign a message' do
expect(assigns(:message)).to be_nil
end
end
And this is the test context for when the message is present in the parameters posted to the controller action.
context 'when params[:message] is present' do
before { post :show, { message: 'great test!' } }
it 'assigns the message from params' do
expect(assigns(:message)).to eq ‘great test!’
end
end
To test Ruby on Rails views, you place the test in the matching spec path as the the view in the app folder, then start your RSpec.describe block with the view file path.
The view helper method render produced the view’s rendered HTML, which can be accessed with its corresponding helper method rendered.
If you had a view file called index.html.erb that included code, such as <h1> <%= @message %> </h1>, then this is how you can test the assignment to the variable.
require 'spec_helper'
RSpec.describe 'views/index.html.erb'
before do
assign(:message, 'great test!')
render
end
it 'should display the message' do
expect(rendered).to include 'great test!'
end
end
Writing effective tests not only will give you confidence in the intended outcome of your tests but also guide you on how it really works, including discovering and ironing out bugs.
To find out more about how you can write readable tests that cover the core functionality of Rails, check out RSpec for Ruby on Rails’ other helper methods, for example that cover redirections and aspects of ActiveRecord models.