[rspec-users] setting partial stub for just one value and letting obj handle the rest

drewB dbatshaw at gmail.com
Thu Apr 1 18:29:43 EDT 2010


For anyone who might come across this message looking for a solution
to the same problem, I wrote the following function to take care of it
(http://gist.github.com/352449)

def stub_find_for_specific_values(model, stubs)
  model.stub!(:find).at_least(1).and_return do |id|
    if stubs.has_key? id
      stubs[id]
    else
      model.find_by_id(id)
    end
  end
end

#example below will return the mock_user if its id is search for
otherwise find will search as normal
mock_user = mock_model(User)
stub_find_for_specific_values(User, mock_user.id => mock_user)

On Apr 1, 3:12 pm, drewB <dbats... at gmail.com> wrote:
> David, thanks for your response.
>
> Matt, I totally hear you.  In this contrived example, you probably
> could but in the project I am working on it would be very difficult.
> One of the challenges of joining a project already in progress...
>
> On Apr 1, 1:45 pm, Matt Wynne <m... at mattwynne.net> wrote:
>
> > On 1 Apr 2010, at 21:35, David Chelimsky wrote:
>
> > > On Apr 1, 2010, at 3:14 PM, drewB wrote:
>
> > >> Occasionally, I find myself in a situation where I want to have a  
> > >> mock
> > >> obj returned if a method is called with a particular argument but
> > >> handled normally otherwise.  For example, lets say I have a Model
> > >> named User and I am specing a controller that sends messages from one
> > >> user to another.  When User.find is called for the user who is making
> > >> the request I want it to run normally but when User.find is called  
> > >> for
> > >> the receiver I want it to return a mocked obj.  In this case, I can  
> > >> do
> > >> something like (http://gist.github.com/352305):
>
> > >> user = mock_model(User)
> > >> User.stub!(:find).at_least(1).and_return do |id|
> > >>   if id == mock_user.id.to_s
> > >>     user
> > >>   else
> > >>     User.find_by_id(id)
> > >>   end
> > >> end
>
> > >> If I didn't have another method that allowed me to find a User by  
> > >> it's
> > >> id this won't work.
>
> > >> Is there an easier way to accomplish this?
>
> > > Not really. When you stub a method, the framework overrides that  
> > > method with its own implementation. There's no mechanism in place to  
> > > say "pass the message onto the real object if it doesn't have the  
> > > arguments I'm interested in." I'm not sure of any framework that  
> > > does that. Maybe RR, but I'm not sure.
>
> > > Good luck.
> > > David
>
> > I can't help but chime in here that I would be pretty irritated to  
> > come across a test that mixed up using mocks and real objects,  
> > especially when they're the same class. Can you not use a mock for the  
> > other instance of User too?
>
> > > _______________________________________________
> > > rspec-users mailing list
> > > rspec-us... at rubyforge.org
> > >http://rubyforge.org/mailman/listinfo/rspec-users
>
> > cheers,
> > Matt
>
> >http://mattwynne.net
> > +447974 430184
>
> > _______________________________________________
> > rspec-users mailing list
> > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
>
> _______________________________________________
> rspec-users mailing list
> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users


More information about the rspec-users mailing list