Assigns in Ruby on Rails — How you can test instance variables in views and controllers

Written by ryanwhocodes | Published 2018/06/13
Tech Story Tags: assigns-in-ruby-on-rails | ruby | ruby-on-rails | test-instance-variables | rspec

TLDRvia the TL;DR App

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.

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.

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.

Read more from ryanwhocodes

Read more


Published by HackerNoon on 2018/06/13