ryanwhocodes Jun 13, 2018 · 3 min read

Assigns in Ruby on Rails - How you can test views and controllers

An explanation of assigns and how to use it to test instance variables in Ruby on Rails views and controllers.

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.

Contents

How assign and assigns works

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.

Controller tests

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

View tests

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

Learn more

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.

  • RSpec docs - These can provide more examples of RSpec syntax for your tests.

  • RSpec for Ruby on Rails - To find out more about how you can write readable tests that cover the core functionality of Rails, check out the other helper methods, for example those that cover redirections and aspects of ActiveRecord models.