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

Costa Shapiro costa at mouldwarp.com
Sat Jul 17 14:18:23 EDT 2010


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.

Thank you for your attention,
Costa.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20100717/390ed5a8/attachment-0001.html>


More information about the rspec-users mailing list