[rspec-users] Problem with Custom matcher and Blocks

Matt Wynne matt at mattwynne.net
Thu Apr 2 15:55:06 EDT 2009


On 2 Apr 2009, at 02:25, Brandon Olivares wrote:

> Hi,
>
> I'm trying to write my first custom matcher.
>
> Here's a bit of my example group.
>
> describe "/contact/index" do
>  include FormMatchers
>
>  before(:each) do
>    render 'contact/index'
>  end
>
>  it "should show the contact form" do
>    response.should have_a_contact_form
>  end
>
>  describe "the contact form" do
>    context "before it has been submitted" do
>      it "should have a subject dropdown box" do
>        response.should have_a_contact_form do |form|
>          form.should have_a_subject_field
>        end
>      end # it "should have a subject dropdown box"
>
>      # This should be failing
>      it "should have a name field" do
>        response.should have_a_contact_form do |form|
>          form.should have_a_name_field
>        end
>      end # it "should have a name field"
>
>      describe "the subject dropdown box" do
>        it "should have a feedback option" do
>          response.should have_a_contact_form do |form|
>            form.should have_a_subject_field do |subject|
>              subject.should have_selector('option', :content =>  
> 'Feedback')
>            end
>          end
>        end # it "should have a feedback option"
>
>        # Etc...
>
>      end # describe "the subject dropdown box"
>
>    end # context "before the form has been submitted"
>
>  end # Describe "the contact form"
>
> end # describe "/contact/index"
>
> Right now, everything before the describe "the subject dropdown box"  
> is
> passing, even though the one testing the name field should not  
> because I've
> not added that field yet.
>
> When it gets to the describe block for the subject, I get:
>
> NoMethodError in '/contact/index the contact form before it has been
> submitted the subject dropdown box should have a blank option'
> undefined method `have_selector' for
> #<FormMatchers::HaveAFormWithID:0x7f3260ac>

#have_selector is part of webrat. Have you required the appropriate  
files so that method is visible to your new matcher class?

> The have_a_contact_form method is as follows:
>
>  def have_a_contact_form &block
>    have_a_form_with_id 'contact', &block
>  end
>
> That calls a have_a_form_with_id method, which calls the  
> haveAFormWithID
> class.
>
> module FormMatchers
>
>  class HaveAFormWithID
>
>    def initialize id, &block
>      @id = id
>      @block = block
>    end
>
>    def matches? response
>      response.should have_selector('form#%s' % [@id]) do |form|
>        !@block or @block.call form
>      end
>    end
>
>    def description
>      "have a form with id #{@id}"
>    end
>
>    def failure_message
>      "expected to have a form with ID #{@id}"
>    end
>
>    def negative_failure_message
>      "expected not to have a form with ID #{@id}"
>    end
>
>  end
>
>  def have_a_form_with_id id, &block
>    HaveAFormWithID.new id, &block
>  end
>
> end
>
> Sorry for all the code. Again this is my first custom matcher, so I  
> could be
> doing something very wrong.
>
> Any help much appreciated.
>
> Thanks,
> Brandon
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users


As a P.S. I hate to take the wind out of your sails here, but I was  
reflecting only today how, after 9 months of using RSpec to TDD our  
Rails app, we have massaged the view specs down to almost nothing. IMO  
99% of the time you should be writing a Cucumber feature instead and  
leaving it at that.

Matt Wynne
http://beta.songkick.com
http://blog.mattwynne.net



More information about the rspec-users mailing list