Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rspec-rails controller testing with assertions and assigns

I have been using rails 5.0.0.1, am new to automation testing and using rspec-rails-3.5.2 for writing automation.

I want to test some basic controller rendering functionality and instance variable assignments. Wrote a controller test case which will check whether get_structure template is rendered and required instance variables are assigned.

describe 'GET #get_structure' do
    context 'get attributes to build tree structure' do
      let(:plan) { FactoryGirl.create(:plan) }

      it 'expects all keys to build structure' do
        get :get_structure, params: { id: 6, school_subdomain: 'chrys' }

        expect(response).to render_template(:get_structure)
        expect(assigns.keys.include?('collection')).to be true
        expect(assigns.keys.include?('structure')).to be true
        expect(assigns.keys.include?('config')).to be true
      end

    end
  end

Once i ran the test cases i realized assert_template is no longer supported due to some security reasons.

NoMethodError: assert_template has been extracted to a gem. To continue using it, add gem 'rails-controller-testing' to your Gemfile.

Since its mentioned in rspec-rails documentation that using rails-controller-testing gem will add back the functionality, i did add it.

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.

I have added rails-controller-testing-1.0.1 gem. Also in the rails-controller-testing gem documentation it is mentioned that

rspec-rails automatically integrates with this gem since version 3.5.0. Adding the gem to your Gemfile is sufficient.

But even after adding, it still throws the same error.

How to resolve this issue? Is there any other way of doing controller tests. I have been banging my head over this for quite sometime. Any help would be appreciated. Thanks in advance.

like image 906
Suganya Avatar asked Feb 02 '17 11:02

Suganya


2 Answers

This question comes up first when one googles for NoMethodError: assert_template has been extracted to a gem. which is the error message that comes up when you try to write controller specs or request specs with either render_template or assigns.

The RSpec documentation still uses this as examples of what to do with both controller and request specs. The rationale of why to use request specs instead of controller specs is listed as an answer elsewhere by Narashima Reddy. But I was still puzzled what to do with either controller or request specs.

The answer seems to be not to. Both assigns and assert_template have been deprecated, which means use of them is a code smell.

Instead of writing a test that checks for whether a template is being rendered, write a test that checks for what will be displayed by that template, or that the response is successful. Instead of writing a test that checks that a value is being assigned, check to see whether the database was changed, or a cookie or session were assigned, or a value is displayed.

This has been a difficult concept for me to grasp, as many online tutorials and even the official rspec docs make reference to this, but the short answer seems to be, don't do it. I hope this helps someone else searching for the assert_template error message.

like image 146
smilingfrog Avatar answered Oct 27 '22 19:10

smilingfrog


From the release notes under Rails: Support for Rails 5 you can find the recommended way to test controllers is Request specs.

For new Rails apps: we don't recommend adding the rails-controller-testing gem to your application. The official recommendation of the Rails team and the RSpec core team is to write request specs instead. Request specs allow you to focus on a single controller action, but unlike controller tests involve the router, the middleware stack, and both rack requests and responses. This adds realism to the test that you are writing, and helps avoid many of the issues that are common in controller specs. In Rails 5, request specs are significantly faster than either request or controller specs were in rails 4, thanks to the work by Eileen Uchitelle1 of the Rails Committer Team.

Request tests hits views also. So there you no need to test with assert_template.

like image 43
Narasimha Reddy - Geeker Avatar answered Oct 27 '22 18:10

Narasimha Reddy - Geeker