Project Ramon

A learning journey from a Ruby noob perspective

Lunch Panoply: Controller Testing


Today, we’ll be covering project lunch_panoply‘s test coverage of controller actions. I’ll be doing a refactor of the model specs and controller specs in a future post.

I’ve been reading a really good ebook entitled Everyday Testing with Rspec: A Practical Approach to Test-driven Development by: Aaron Sumner. It has been extremely helpful in helping me to understand the various nuances to providing good test coverage for a Rails application. I especially found a lot of value in Aaron’s example specs, as well as the test environment setup. I wasn’t using the database_cleaner gem until I purchased his book.

What to Test in a Controller Spec

There are 3 things I’m learning to test inside of my controller action specs:

  1. Testing Controller Response
  2. Testing Returned Data
  3. Testing Redirects, and Renderings in a Controller Action

We’ll be covering each of these three controller behaviors up next.

Testing Controller Responses

Part of a basic controller spec’s coverage should usually include that a controller method returns the HTTP status code we are expecting. It’s also a good idea to include whether we’re expecting a redirect upon success or which view template to render if the spec calls for it.

Lets have a look at an example or two:

Above I’ve just shown an illustration of how to setup a controller spec. If we recall from my last post, there are 3 main steps to setting up any spec.

  • The Setup: Where we establish the scenario typically with Factories
  • The Execution: Creating a method call that triggers the spec to be ran
  • The Verification: We make an assertion to verify our expected results

With this in mind, lets fill out the empty spec block from above:

In line: 7, I’m setting up a Factory instantiation. I’m not using employee = FactoryGirl.create(:employee) because of the configurations available in FactoryGirl to truncate its syntax.

Here’s where and what I’ve added to my spec_helper file.


It is line: 12 that provides the ability to drop the FactoryGirl from every .create or .build method we’ll use in the future.

line: 8 (from the gist before the spec_helper illustration) declares the appropriate HTTP verb and also passes in the parent_id of an Employee. In this case Employee’s parent is a company. Since this is the index action, we don’t need a particular id to pass in for an employee, as all employee objects will be displayed here.

Lines: 9 – 10 is where we make our assertions. We are expecting http success in line: 9 and that this controller action includes a rendering of the :index view. Here’s a look at the actual controller to verify:


And a quick snapshot of the Rails Guides to explain how render automatically includes the :index template even though it’s not specified inside of the above controller action:


Testing Returned Data

Ruby on Rails allows us to verify the data generated by our controller action through 4 collections; assigns, session, cookies and flash. Assigns is typically used most often.

Lets look at how the new controller action is setup:


In the above example we can see that I have separated it 'returns http success' and it 'renders the :new template into separate specs. Something to keep in mind for our refactor post I’d say.

More importantly we can see that the spec it 'assigns a new Employee to employee' is using
the assigns(:employee) pseudo-hash variable in it’s assertion on line: 37. We’re asserting that we are expecting a new instance of Employee to actually be from the class Employee.

The assigns variable allows us access to any instance variable set in the controller method.

Testing Redirects and Renders

We’ve already seen a good example of an assertion to validate a template rendering, and some thorough documentation to best explain whats happening when no call to render in a controller action method is explicitly made.

Lets have a quick look over a few redirect assertions:


I’ve included the entire update action block as an example, inside of the block we’re testing for the location of a specific employee resource representative, covering the case of an employee successfully updating their attributes, and lastly the successful redirect to an employee with updated attributes.

Lets walk through the last spec inside of the with valid attributes context.

on line: 111 we’re just setting up our object via a factory, line: 112 is defining the appropriate HTTP verb, passing in the parent_id and object_id, for routing purposes, and also passing the specific employee attributes that were updated. Finally, we’re asserting that the response should redirect to our employee :show template by listing its associated path name.


Here’s a look at our update controller action with invalid attributes:


I like to imagine myself clicking through the application in order to give me a better sense of the behaviors I’m expecting and guarding against when I’m laying out my pending specs. For instance, we know that if we are at a form on an employee edit page, and update a value with another appropriate value, we are expecting to be redirected back to the show page typically. If we somehow enter in some invalid data/data-type (i.e. accidentally deleting a form_field with a presence validation defined inside it’s model), the convention is for the resourced representation to be re-rendered on the edit page with an error displaying, letting us know our mistake.

I hope that this post on Controller specs have been as insightful for you to read as it was for me to write.

This post wouldn’t be complete without running both of the two contoller_specs I’ve completed so far.

Here’s the output:


Looks green enough to me! Time to push this to github!

Next up, the refactor.

Stay tuned…


Categories: Ruby on rails

Tags: ,

2 replies


  1. Getting Started with TDD in Rails -
  2. Rails Testing, Getting Started with TDD Best Practices

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s