I used to do the following when I used rspec mocks. user = mock_model(User) find_method = User.method(:find) User.stub!(:find).at_least(1).and_return do |id| if id == mock_user.id.to_s user else find_method.call(id) # May need to instance_eval here, but I think .call is sufficient. end end
In fact this sort of inspired me to mock.proxy method call. Of course YMMV :-) On Thu, Apr 1, 2010 at 3:29 PM, drewB <dbats...@gmail.com> wrote: > 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...@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...@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...@rubyforge.org >> > >http://rubyforge.org/mailman/listinfo/rspec-users >> >> > cheers, >> > Matt >> >> >http://mattwynne.net >> > +447974 430184 >> >> > _______________________________________________ >> > rspec-users mailing list >> > rspec-us...@rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users >> >> _______________________________________________ >> rspec-users mailing list >> rspec-us...@rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users