[Rspec-devel] New proc.should_increment method

David Chelimsky dchelimsky at gmail.com
Fri Jul 14 16:28:44 EDT 2006

On 7/14/06, aslak hellesoy <aslak.hellesoy at gmail.com> wrote:
> That sounds good. I'm looking forward to that.
> One thing I'd like to instead of:
>   thing = mock("thing")
> is to do:
>   thing = mock(Thing) # passing a class rather than a string
The way it works now does something similar, but is implemented
differently. You tell a class to act like a mock:

class Thing; acts_as_mock; end

Then you can do this:

thing = Thing.new

post :create



(Once fully  integrated w/ rspec the verification should be automagic.)

Now you've got a handle on the object that is acting like a mock. If
you want you can do this:

thing = Mock.new("thing")

instead. Then you'd get an instance of Mock rather than an instance of
 Thing that's acting like one.

Also, the way acts_as_mock handles messages is a bit different from
rspecs current mocks. Rather than using message_missing and comparing
the message to expectations, it actually adds methods to the mock when
you set expectations. So when you do this:


this is what happens internally:

        def should_receive message
          (class << self; self; end).class_eval do
            define_method(message.to_s, lambda {received_message message})
          @messages_expected << message

received_message (which gets called by the newly created method) then
checks against @messages_expected. There's more to it than that, but
that's the basic idea.

More soon........

> -and have the mock fail if you tell it to expect a message that is not defined by Thing.

Interesting, but that goes against something I'm shooting for in rails
controller tests. I want to decouple them completely from the db.
Since AR defines methods on the fly based on DB structure, those
methods wouldn't be there and the mock would fail.

There is something interesting here though - maybe we could have an
argument to acts_as_mock that tells it to behave this way when we want
to (raising flags when methods aren't part of the class), but
otherwise not.

When testing controllers, we could set that flag and force the
controller to only call methods that we actually write in to the model
classes, and therefore not use any of the read accessors that are
created for attributes by AR.

Then, when testing views, we would turn the flag off and tell the mock
to return an empty string for any getters it calls that we haven't
specified how the mock should behave.

Too complex? Maybe. This is all stuff we can add later if we agree it
makes sense. First things first.


More information about the Rspec-devel mailing list