[Rspec-devel] define_instance_method, stub_with, and mock_with

Brian Takita brian.takita at gmail.com
Sun Aug 27 16:31:05 EDT 2006


>
> As for the idea you are presenting, in general, I think that mocking
> methods on real instances is  a risky proposition.


Yes, I agree with you about the partial mocking. mock_with was an alias of
stub_with, but that has to do with inaccurately definining a mock.

Using a stub to introduce a mock is useful though.

specify "should display person when show is requested" do
>  person = mock("person")
>  Person.should_receive(:find).with(123).and_return(person)
>  person.should_receive(:name).and_return("Joe")
>  get 'show'
> end
>
> specify "should ask Person for a new one when create is requested" do
>  person = mock("person")
>  Person.should_receive(:new).and_return(person)
>  get 'create'
> end
>

I noticed that Stubba does do this, with a different syntax. I tried
introducing it at my workplace, but it caused issues with other tests.

On 8/27/06, David Chelimsky <dchelimsky at gmail.com> wrote:
>
> On 8/27/06, Brian Takita <brian.takita at gmail.com> wrote:
> > Hello,
> >
> > At work we came up with a trio of methods that mock out methods in an
> > object.
> >
> > define_instance_method
> > stub_with
> > mock_withFunny thing is around the same time, this was posted.
> >
> http://blog.seagul.co.uk/articles/2006/06/30/very-very-lightweight-mocking-ish
> >
> > Here is a snippit from that article.
> >
> > class Object
> >
> >   def metaclass
> >     class << self; self; end
> >    end
> >
> >   def define_instance_method(sym, &block)
> >      metaclass.__send__(:define_method, sym, &block)
> >   end
> >
> >   def stub_instance_method(sym, &block)
> >      raise "#{self} does not respond to <#{sym}> and therefore cannot be
> > stubbed" unless self.respond_to?(sym)
> >      define_instance_method(sym, &block)
> >   end
> >
> >   def __log__
> >     @__log__ ||= []
> >   end
> >
> >  end
> >
> > So you can use this like:
> > o = Object.new
> >  o.define_instance_method(:foo) do
> >   :bar
> >  end
> > o.foo # return :bar
> >
> > We went a little further by adding the mock_with and stub_with methods,
> > which take a Hash and allow you to mock out the method names
> corresponding
> > to the keys.
> >
> > For example,
> > o = Object.new
> > two_value = 2
> >  o.stub_with(:one => 1, :two => proc {two_value})
> > o.one # returns 1
> > o.two # returns 2
> >
> >  o = Object.new
> > mock_action = mock("mock_action")
> >  mock_action.should_receive(:something).with(:grey_poupon)
> > o.mock_with (:receive => proc {mock_action)}
> > o.receive.something(:grey_poupon)
> >
> > David, I also remember you where working on acts_as_mock. This has
> helped us
> > with our tests and I think it would also make using specs more
> convenient
> > and easier to read.
> > What does everybody think? If it sounds good, I'll create a patch.
>
> I started working on acts_as_mock because rails forces us to use
> static methods to find objects, which couples us to the database in
> our controller specs:
>
> Person.find(123)
>
> In retrospect, all we really need is the ability to mock class level
> methods and then return a mock:
>
> specify "should display person when show is requested" do
>   person = mock("person")
>   Person.should_receive(:find).with(123).and_return(person)
>   person.should_receive(:name).and_return("Joe")
>   get 'show'
> end
>
> specify "should ask Person for a new one when create is requested" do
>   person = mock("person")
>   Person.should_receive(:new).and_return(person)
>   get 'create'
> end
>
> The code for this much is already in a branch, so I'll revisit that in
> the next few days.
>
> As for the idea you are presenting, in general, I think that mocking
> methods on real instances is  a risky proposition. I've seen this
> result in tests that are very difficult to understand when they fail,
> as some methods on the instance are mocked and some are not. I also
> have yet to see a case where   using partial mocks is a better
> decision than improving the decoupling in the system under test.
>
> That's just my 2 cents. Anyone else?
>
> David
> _______________________________________________
> Rspec-devel mailing list
> Rspec-devel at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/rspec-devel/attachments/20060827/10c0a3af/attachment.html 


More information about the Rspec-devel mailing list