[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