[rspec-users] DRYer controller specs

David Chelimsky
2007-04-27T14:20:03Z

On 4/11/07, nicholas a. evans <nick at ekenosen.net>
wrote:
> So, I''ve been following the recommendations for controller specs
here:
>
http://blog.davidchelimsky.net/articles/2006/11/09/tutorial-rspec-stubs-and-mocks
>
> Most notably: a single expectation per specify block; the setup block
> contains only stubs; mock expectations each get their own specify
> block.  (I''m still using 0.8, so I haven''t gotten the
describe/it
> goodness yet.)
>
> I don''t really mind the stub/mock duplication (between setup and
the
> specifications).  What''s annoying me is the action duplication.
"get
> ''create''" is called in each specify block, sometimes
before the actual
> specification, sometimes afterward, depending on whether it''s a
mock
> expectation or a state expectation.
>
> So I played around with creating the following module and then
> extending my context with it.
>
> module MockSpecHelpers
>   def expect_that_it(msg)
>     specify msg do
>       yield
>       action
>     end
>   end
>   def then_it(msg)
>     specify msg do
>       action
>       yield
>     end
>   end
> end
>
> in the context block, I would then "def action do get
''create'' end".
> And I would replace the following specify blocks
>
>   specify "should create a new person on GET to create" do
>     Person.should_receive(:new).and_return(@person)
>     get ''create''
>   end
>
>   specify "should assign new person to template on GET to create"
do
>     get ''create''
>     assigns[:person].should_be @person
>   end
>
> with
>
>   expect_that_it "should create a new person on GET to create" do
>     Person.should_receive(:new).and_return(@person)
>   end
>
>   then_it "should assign new person to template on GET to create"
do
>     assigns[:person].should_be @person
>   end

I like the idea of binding the examples to some method that gets run
before or after the example. There is a similar RFE already in the
tracker
http://rubyforge.org/tracker/?func=detail&group_id=797&aid=10285&atid=3152.

The problem is coming up with the right language. It think
expect_that_it and then_it would encourage one to write all of the
expect_that_its first and the then_its last. It also seems to indicate
a relationship between the examples, even though no such relationship
exists.

In the RFE I mentioned, I proposed something like ...

  it "should do something", during_event do

That seems to work well, but its counterpart ...

  it "should leave some state", after_event do

leaves me cold. It especially fails to align w/ your example "should
assign new person to template on GET to create", which seems like a
great way to express the behaviour, but followed by "after_event"
doesn''t really read correctly.

Any other suggestions?

In general, I''m much more inclined to favor an additional parameter
passed to #it over a new method name.

Cheers,
David