[rspec-devel] mock frameworks

Brian Takita brian.takita at gmail.com
Sun May 20 00:47:23 EDT 2007


On 5/14/07, James Mead <jamesmead44 at gmail.com> wrote:
> Hi Brian,
>
> On 14/05/07, Brian Takita <brian.takita at gmail.com> wrote:
> > I'm considering using Mocha + Mocha Shot.
> > http://rubyforge.org/projects/mocha-shot
>
> Nice one! I like some of the ideas in this. Sorry not to have been
> more responsive - things are as busy as ever at Reevoo.

Thank you problem. I like the idea of plugin gems. It provides a nice
experiment to see if something works.

>
> > There are some things that are in Rspec's mocking framework that are missing
> > in Mocha though.
> > For example, in spec/mock, #and_return takes a block that gets executed and
> > accepts the arguments passed to the method.
>
> The Mocha returns() method can currently take an instance of a Proc
> which you can use to define more complex behaviour. However it is true
> that the parameters of the method are not passed to this Proc. But
> this is intentional. Because you are completely and deterministically
> in control of all the objects involved in the test, you should know
> what sequence of return values you need to return from the mock. So
> you can use something like...
>
> m = mock()
> m.stubs(:method).returns(1, 2, 3).then.raises(Exception).then.returns(5).
>
> The fact that you need to know the parameters being passed in to the
> stubbed method in order to work out what to return is probably a sign
> that you are testing too much at once.
>
> Anyway, if you need that degree of control, why not simply use
> define_method. Or use a Rails-style "mock" (i.e. hard-coded fake
> class).
>
> For similar reasons the ability of the returns() method to take an
> instance of a Proc will probably be phased out soon.
>
> Does that make sense?

That makes sense, and I understand how limitation can help make
something as dangerous as mocks safer.

One pattern I have been doing is as follows:

the_method = foo.method(:the_method)
foo.should_receive(:the_method).and_return(&the_method)

This acts like a "probe".

I use the mock only to verify the method was called. This also
verifies that the method exists on the object. Of course most of the
time I can do:

value = foo.the_method
foo.expects(:the_method).returns(value)

The block is also useful as a catchall to verify certain values when
the with expectation handlers and not sufficient.

value = nil
foo.should_receive(:the_method).with(:anything).and_return {|obj| value = obj}
value.should ...

I imagine that lots of handlers would mitigate this.

Brian

> --
> James.
> http://blog.floehopper.org
> _______________________________________________
> rspec-devel mailing list
> rspec-devel at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-devel
>


More information about the rspec-devel mailing list