[rspec-users] Working outside-in with Cucumber and RSpec

Ben Mabey ben at benmabey.com
Sat Oct 25 19:03:17 EDT 2008

Pat Maddox wrote:
>> If I say we're going to
>> skip controller specs because they don't add enough value, how do I
>> know that won't be interpreted as "controller specs are too hard,
>> don't write specs when it's hard"?
> I have a three-headed defense of rarely writing controller specs
> anymore:
> * Controllers are already exercised by cucumber
> * Most of the logic is provided by the framework.
> * Controllers tend to be procedural instead of OO
> The first one should be obvious.  As for the second, since I'm not
> actually writing most of the code, I'm not that worried about it
> breaking.
> Procedural code is no fun to test.  You have to use a lot of mocks, and
> your example looks more or less the same as the production code.  Blech.
> Rails controllers don't encapsulate state or iteration, the only
> encapsulation-worthy behavior usually is a simple if statement.
> Controllers also typically aren't very cohesive, you're never going to
> call more than one method on them.  Put simply, controllers, as used in
> Rails, are a collection of transaction scripts grouped together by the
> resource on which they operate.
> Now, when I don't write cucumber features, I absolutely do write
> controller specs.  But I'll have those hit the db, with integrate_views
> turned on, acting essentially as an integration test.  The thing is,
> there isn't a lot of value in writing both features and controller
> specs, unless your controllers have some pretty complex logic (which
> they shouldn't when using Rails!)
> So I guess that were I to be teaching someone this stuff, I would
> explain the benefits of testing, and evaluate how controller specs add
> value.  Specifically, they don't add regression value over features, and
> they provide marginal design value, particularly if you follow typical
> Rails controller patterns.  I would explain that I don't see much
> benefit to the controller specs, and that they're kinda tough to test
> because they're not very OO.  And I'd use that as an opportunity to
> notice smells - when you're writing specs and it's difficult, and you
> control all the code, then your code could probably use some design
> improvements.
> But yeah, I like working outside-in :)
> Pat
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

I agree with most of this.  For a purely RESTful controller I like to 
use a plugin, like make_resourceful, that will take care of all the 
boilerplate code that becomes very tedious to spec out and write.  Since 
the plugins are tested I can just rely that coverage alongside my 
scenarios going through the full stack.  However, once I need to go out 
of the ordinary RESTful controller I usually always still write specs 
for those actions using mocks.  My two reasons for doing this is a) 
allow for interface discovery with mocks and b) to prevent logic from 
seeping into the controllers.  Writing code examples for controllers in 
a purely interaction-based way can be laborious and it becomes extremely 
painful if you put actual business logic in them.   I think that pain is 
a good thing because it reminds less experienced people on your team 
(and more experienced people too sometimes :) ) that controllers 
shouldn't get too big and that they should be pushing the responsibility 
into other objects (be that AR or regular ruby objects.) 

So while I agree completely that controller specs don't offer regression 
value over scenarios I do place more value on the design aspect I think 
they provide.  In the past I have been able to detect feature envy and a 
number of other code smells within my controllers via my controller 
examples that I don't think I would of noticed and/or been motivated 
enough to refactor them into the right level.  Again, I can totally 
understand your point of view and even agree with it.  I think if a team 
is experienced and disciplined enough then writing controller specs 
could be skipped... just keep a look out for "broken windows" or else 
the whole controller neighborhood will start seeping tiny facets of 
business logic. :)

Oh, and to an earlier point in this thread.. I can't remember the last 
time I wrote a view spec.  Any semi-interesting logic that for some 
reason needs to be in the view I will place in a helper and then spec 
that out.

+1 on working outside-in. :)


More information about the rspec-users mailing list