[rspec-users] DRYer controller specs

David Chelimsky dchelimsky at gmail.com
Fri Apr 27 10:20:03 EDT 2007


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


More information about the rspec-users mailing list