[rspec-users] Data-wise context combination for controller speccing

David Chelimsky dchelimsky at gmail.com
Sat Jul 17 19:10:50 EDT 2010


On Jul 17, 2010, at 1:18 PM, Costa Shapiro wrote:

> Hello,
> 
> I've been thinking of how to express my idea in code, but since I've never been involved in RSpec development, I'd better have some feedback here first.
> The feature suggestion below applies to any controller-like code under spec, i.e. a stateless module producing output or just altering its data store (it doesn't necessarily have to be a C of the MVC, but I suppose merb/rails developers will particularly appreciate it).
> 
> Here is a skimmed sample to illustrate the pain:
> 
>     describe BookController do
>     
>       context "registering a book" do
>     
>         specify "from a new author on a new subject" do
>           auth = mock(:name => 'John Doe')
>           Author.should_receive(:find_
> by_name).and_return(nil)
>           Author.should_receive(:new).and_return(auth)
>           auth.should_receive(:save).and_return(true)
>     
>           subj = mock(:short => 'Mockery')
>           Subject.should_receive(:find_by_short).and_return(nil)
>           Subject.should_receive(:new).and_return(subj)
>           subj.should_receive(:save).and_return(true)
>     
>           title = 'Specs on Steroids'
>     
>           book = mock
>           Book.should_receive(:new).and_return(book)
>           book.should_receive(:save).and_return(true)
>     
>           post :register :author => auth.name, :title => title, :subject => subj.short
>           response.should be_success
>         end
>     
>         specify "from a known author on a new subject" do
>           auth = mock(:name => 'Joe Dohn')
>           Author.should_receive(:find_by_name).and_return(auth)
>     
>           subj = mock(:short => 'Mockery')
>           Subject.should_receive(:find_by_short).and_return(nil)
>           Subject.should_receive(:new).and_return(subj)
>           subj.should_receive(:save).and_return(true)
>     
>           title = 'Specs on Steroids II'
>     
>           book = mock
>           Book.should_receive(:new).and_return(book)
>           book.should_receive(:save).and_return(true)
>     
>           post :register :author => auth.name, :title => title, :subject => subj.short
>           response.should be_success
>         end
>     
>         specify "from a known author on a known subject" do
>           auth = mock(:name => 'Joe Dohn')
>           Author.should_receive(:find_by_name).and_return(auth)
>     
>           subj = mock(:short => 'Forgery')
>           Subject.should_receive(:find_by_short).and_return(subj)
>     
>           #...
>         end
>     
>         specify "from a new author on a known subject" do
>           #...
>         end
>       end
>     end
> 
> 
> And this is what I have in mind for doing exactly the same job:
> 
>     describe BookController do
>     
>       context "registering a book" do
>     
>         before :any, "from a new author", :author do
>           @auth = mock(:name => 'John Doe')
>           Author.should_receive(:find_by_name).and_return(nil)
>           Author.should_receive(:new).and_return(@auth)
>           @auth.should_receive(:save).and_return(true)
>         end
>     
>         before :any, "from a known author", :author do
>           @auth = mock(:name => 'Joe Dohn')
>           Author.should_receive(:find_by_name).and_return(@auth)
>         end
>     
>         before :any, "on a new subject", :subject do
>           @subj = mock(:short => 'Mockery')
>           Subject.should_receive(:find_by_short).and_return(nil)
>           Subject.should_receive(:new).and_return(@subj)
>           @subj.should_receive(:save).and_return(true)
>         end
>     
>         before :any, "on a known subject", :subject do
>             @subj = mock(:name => 'Joe Dohn')
>             Subject.should_receive(:find_by_name).and_return(@subj)
>         end
>     
>         it "should succeed", :with => [:author, :subject] do
>           title = 'Specs on Steroids X'
>     
>           post :register :author => @auth.name, :title => title, :subject => @subj.short
>           response.should be_success
>         end
>       end
>     end
> 
> A run of such specs will effectively multiply the tests — automatically — choosing before and after blocks as specified.
> I'm sorry, I haven't thought the DSL through, but I hope the main idea can be seen: contexts do not have to be hierarchical.
> In my opinion, adding some sort of context selection+combination capabilities (AOP-style) will contribute greatly to the expressiveness of the spec language.

I think the idea of mixing/matching sub-contexts is very interesting, but it definitely needs from fleshing out. It would have to be easy to read/understand in the spec file as well as the output.

Also, this only works if every combination should behave the same way. I think we'd need a means of saying "given these combinations of data, expect these outcomes".

Anybody else have thoughts on this?

Cheers,
David


> Thank you for your attention,
> Costa.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20100717/9f190fdf/attachment-0001.html>


More information about the rspec-users mailing list