Is it possible to stub a method in a parent class so that all subclass instances are stubbed in rspec?
Asked Answered
B

3

10

Given a parent class Fruit and its subclasses Apple and Banana, is it possible to stub the method foo defined in Fruit, so that any calls to method foo on any instances of Apple and Banana are stubbed?

class Fruit
  def foo
    puts "some magic in Fruit"
  end
end
class Banana < Fruit
  ...
end
class Apple < Fruit
 ...
end

Fruit.any_instance.stubs(:foo) did not work and it looks like it only stubs for instances of Fruit. Is there a simple way to achieve this other than calling stubs for every subclasses?

Found this link raising the similar question but it looks like it has not been answered yet. http://groups.google.com/group/mocha-developer/browse_thread/thread/99981af7c86dad5e

Bulb answered 24/9, 2011 at 13:20 Comment(0)
L
10

This probably isn't the cleanest solution but it works:

Fruit.subclasses.each{|c| c.any_instance.stubs(:foo)}
Loisloise answered 25/9, 2011 at 18:32 Comment(2)
Yes, it works for this simple example. But it would be a bit clumsy if there are many sub classes. Also it does not work on ActiveRecord models, because the method is overridden in base.rb. I was actually looking for a way to stub a method for all controllers and models.Bulb
This method worked well for me, except using c.constantize.any_instance.stubs(:foo)Hargis
T
1

UPDATE of @weexpectedTHIS answer for Rspec 3.6:

 Fruit.subclasses.each do |klass|
    allow_any_instance_of(klass).to receive(:foo).and_return(<return_value>)
 end
Tacitus answered 23/6, 2017 at 12:24 Comment(0)
N
0

If your subclasses have subclasses, you may have to traverse them all recursively. I did something like this:

def stub_subclasses(clazz)
  clazz.any_instance.stubs(:foo).returns(false)
  clazz.subclasses.each do |c|
    stub_subclasses(c)
  end
end
stub_subclasses(Fruit)
Nila answered 2/5, 2014 at 18:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.