My Beautiful Controller Spec

Posted by John Wulff Fri, 15 Feb 2008 23:21:00 GMT

Today I spent a few hours refining my controller rspec pattern. I’m really pleased with it.

This controller:
class AssignmentsController < ApplicationController  
  def index
    if params[:person_id]
      @person = Person.find params[:person_id]
      @assignments = @person.assignments
      @title = "Assignments for #{@person}"
    elsif params[:course_id]
      @course = Course.find params[:course_id]
      @assignments = @course.assignments
      @title = "Assignments for #{@course}"
    else
      @assignments = Assignment.find :all
      @title = "All Assignments"
    end

    @ical_url = url_for({ :format => :ics }.merge(params))
    @rss_url = url_for({ :format => :rss }.merge(params))
  end
end
Gets this spec:
require File.dirname(__FILE__) + '/../spec_helper'

describe AssignmentsController do
  describe 'index action GET request with' do
    describe 'no parameters' do
      before(:each)                    do get 'index' end
      it 'should successfully respond' do response.should be_success end
      it 'should assign a title'       do assigns[:title].should == 'All Assignments' end
      it 'should assign assignments'   do assigns[:assignments].should == Assignment.find(:all) end
    end

    describe 'a valid person_id' do
      before(:each)                    do get 'index', :person_id => (@person = test_person) end
      it 'should successfully respond' do response.should be_success end
      it 'should assign a title'       do assigns[:title].should == "Assignments for #{@person}" end
      it 'should assign assignments'   do assigns[:assignments].should == @person.assignments end
    end

    describe 'a valid course_id' do
      before(:each)                    do get 'index', :course_id => (@course = test_course) end
      it 'should successfully respond' do response.should be_success end
      it 'should assign a title'       do assigns[:title].should == "Assignments for #{@course}" end
      it 'should assign assignments'   do assigns[:assignments].should == @course.assignments end
    end

    describe 'any valid parameters' do
      before(:each)                    do get 'index' end
      it 'should assign a rss_url'     do assigns[:rss_url].should == 'http://test.host/assignments.rss' end
      it 'should assign an ical_url'   do assigns[:ical_url].should == 'http://test.host/assignments.ics' end
    end
  end
end

Liberal use of nesting, alignment, and inline assignments, hooray.

Beautiful specs mean I’m that much more likely to actually write them…

Can it get any better?

Simple vs. DRY Rails Specs

Posted by John Wulff Sun, 08 Apr 2007 01:16:00 GMT

I’m toying with two different styles of Rails Specification (RSpec) testing. One is easier to read, the other is much more DRY (do not repeat yourself). Which do you think is better?

DRY:
specify "has many ContentTerms" do
  content_term_ids = [ 1, 2, 3 ]
  @content.content_terms.should have(content_term_ids.size).records
  for id in content_term_ids
    @content.content_terms.should include(ContentTerm.find(id))
  end
end
Simple:
specify "has many ContentTerms" do
  @content.content_terms.should have(3).records
  @content.content_terms.should include(ContentTerm.find(1))
  @content.content_terms.should include(ContentTerm.find(2))
  @content.content_terms.should include(ContentTerm.find(3))
end

The DRY version makes me feel special but the simpler version is much easier on my brain. I think I’ll go with the simple one… for now.