[Rspec-users] Mocking causes empty specification blocks

Chris Roos chrisjroos at gmail.com
Mon Jul 24 18:23:42 EDT 2006


On 7/24/06, David Chelimsky <dchelimsky at gmail.com> wrote:
> On 7/24/06, Chris Roos <chrisjroos at gmail.com> wrote:
> > On 7/24/06, David Chelimsky <dchelimsky at gmail.com> wrote:
> > > On 7/24/06, Chris Roos <chrisjroos at gmail.com> wrote:
> > > > I've found myself mocking out a published api in my set-up method.
> > > > This has led to some contexts having a large set-up and empty
> > > > specifications.  As the mocks get auto-verified, the specification
> > > > blocks have nothing to do but serve as documentation.  Does this sound
> > > > bad?
> > >
> > > What is it that you are specifying? Why are there no statements in the specs?
> > >
> > I'm specifying the relationship between my object and the mocks.  The
> > expectations on the mock object are created in the setup block and
> > auto-verified in my empty specification.
> >
> > I've pasted an example context below.  I'm actually wanting to ensure
> > that a validator doesn't get installed.  All the expectations (bar
> > :header_row?) are irrelevant in this case; but I don't think I can use
> > a null_object mock as I then wouldn't get notified if we try to
> > install a validator.
> >
> > Chris
> >
> > -- spec --
> >
> > context "A processed feed validator with one header row but no
> > required headers" do
> >
> >   setup do
> >     header_row = mock('header_row')
> >     header_row.should_receive(:header_row?).and_return(true)
> >     header_row.should_receive(:extend).with(Validatable)
> >     header_row.should_receive(:errors)
> >     header_row.should_receive(:fields).and_return([[]])
> >     io = [header_row]
> >     feed_validator = FeedValidator.new(io)
> >     feed_validator.process
> >   end
> >
> >   specify "should not install an empty header validator" do
> >   end
> >
> > end
>
> It strikes me that you're mixing setup w/ events. Since your spec is
> that "should not install an empty header validator", then put
> something in the specify block that indicates when the installation is
> happening, and perhaps the specific expectation as well. For example:
>
> context "A processed feed validator with one header row but no
> required headers" do
>
>  setup do
>    @header_row = mock('header_row')
>    @header_row.should_receive(:header_row?).and_return(true)
>    @header_row.should_receive(:extend).with(Validatable)
>    @header_row.should_receive(:errors)
>    @io = [header_row]
>    @feed_validator = FeedValidator.new(io)
>  end
>
>  specify "should not install an empty header validator" do
>    @header_row.should_receive(:fields).and_return([[]])
>    @feed_validator.process
>  end
>
> end
>
Maybe it would help if I pasted how I would like the code to look..

context "A feed validator with one header row but no required headers" do

 setup do
   @header_row = mock('header_row')
   @header_row.should_receive(:header_row?).and_return(true)
   io = [@header_row]
   @feed_validator = FeedValidator.new(io)
 end

 specify "should not install an empty header validator" do
   @header_row.should_not_receive(:install_validators)
   @feed_validator.process
 end

end

Anything that was in my original example that is not above was there
because otherwise my mock will complain of unexpected methods being
called.  I don't think I'm able to use the :null_object option as I'm
relying on the fact that my mock complains if the install_validators
message is sent.  Note the made up 'should_not_reveive' method above.
Maybe if I had something like this then I could indeed use the
null_object option?

As for having the feed_validator.process line in the setup, that was
kinda taken from the rSpec tutorial (re 'should not be empty after
push').  I was thinking along the lines of this object already being
processed.

Thanks for the help guys.

Chris

> Also, you can use null_object to tell the mock to not worry about
> calls you don't specify. So, for example, you could do this in setup:
>
>    @header_row = mock('header_row', :null_object => true)
>
> and then you don't need this in your setup:
>
>    @header_row.should_receive(:extend).with(Validatable)
>    @header_row.should_receive(:errors)
>
> The only things you need in the setup would be the messages that
> result in some return value. Then you could have separate specify
> blocks for "should supply errors" and "should extend using a
> Validitable" (for example).
> _______________________________________________
> Rspec-users mailing list
> Rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the Rspec-users mailing list