New RSpec Pattern to DRY up Your Controller Specs
Published: November 6th, 2007There was a feature request on the RSpec mailing list, or the RSpec tracker on drying up the controller specs. Here’s a solution that David Chelmisky came up with; there’s even a snippet of helper code so you can incorporate this right away into your specs!
One of RSpec’s developers, David Chelimsky, released a little helper to
remedy a clunky pattern1 in the controller
specs2. David gave the following example as what is considered “clunky”, I’m sure you all do it, I know I do.
describe PersonController, "handling failed POST to create" do def do_post post :create, invalid_arguments end it "should redisplay the create form" do do_post response.should render_template("people/new") end it "should try to create a Person" do Person.should_receive(:create).with(invalid_arguments).and_return(false) do_post end end
So, as a solution to the clunkiness in the example above, David proposed this:
describe PersonController, "handling failed POST to create" do def do_post post :create, invalid_arguments end it "should redisplay the create form" do after_post do response.should render_template("people/new") end end it "should try to create a Person" do during_post do Person.should_receive(:create).with(invalid_arguments).and_return(false) end end end
I honestly have to say, that I like this style a lot. This style adds a lot more verbosity, and clarity to the point of controller speccing. I know that if I
were a beginner all over again, this would have removed a lot of confusion that I went through during those days.
The Helper
If you’d like to use this, you can simply copy and paste the following code and put it into spec_helper.rb:
[:get, :post, :put, :delete, :render].each do |action| eval %Q{ def before_#{action} yield do_#{action} end alias during_#{action} before_#{action} def after_#{action} do_#{action} yield end } end
Thanks to David Chelimsky for writing this out. I think this has potential to go into RSpec’s ruby_on_rails core, so far it’s just a helper.
How do you feel about this new pattern? Could you see this going into the RSpec ruby_on_rails core?
- There was a suggestion in the rspec tracker, or the mailing list about a feature to dry up the controller specs. [↩]
- Specs are basically tests, but under a different mentality. RSpec adopts the philosophy of Behavior Driven Development, which imposes this new mentality
of covering your code. [↩]

+1 for this going in rspec core !
It’s super annoying to put the flash or render in the wrong place in a test, and get some non-helpful message. This puts a little flavor in so you’re more likely to behave yourself :)
Ready. Set. Go.
In terms of the formatting, you're allowed to use markdown, textile, or basic html; it's truly up to you -- what strikes your fancy?
You don't have to worry about your e-mail address being sold to a russian-spam-mafia. I'm only going to use it for my own weird needs; like asking you out for a date on a lonely night of coding.