How can I mock super in ruby using rspec?
You can't mock super
, and you shouldn't. When you mock something, you are verifying that a particular message is received, and super
is not a message -- it's a keyword.
Instead, figure out what behavior of this class will change if the super
call is missing, and write an example that exercises and verifies that behavior.
A good way to test this is to set an expectation of some action taken by the superclass - example :
class Some::Thing < Some def instance_method super endend
and the super class:
class Some def instance_method another_method end def self.another_method # not private! 'does a thing' endend
now test :
describe '#instance_method' do it 'appropriately triggers the super class method' do sawm = Some::Thing.new expect(sawm).to receive(:another_method) sawm.instance_method end end
All This Determines Is That Super Was Called On the Superclass
This pattern's usefulness is dependent on how you structure your tests/what expectations you have of the child/derivative class' mutation by way of the super
method being applied.
Also - pay close attention to class
and instance
methods, you will need to adjust allows
and expects
accordingly
YMMV
As @myron suggested you probably want to test the behavior happening in super
.
But if you really want to do this, you could do:
expect_any_instance_of(A).to receive(:instance_method).and_call_original
Assuming
class B < A def instance_method super endendclass A def instance_method # endend
Disclaimer expect_any_instance_of
are a mark of weak test (see):
This feature is sometimes useful when working with legacy code, thoughin general we discourage its use for a number of reasons:
The rspec-mocks API is designed for individual object instances, butthis feature operates on entire classes of objects. As a result thereare some semantically confusing edge cases. For example, inexpect_any_instance_of(Widget).to receive(:name).twice it isn't clearwhether a specific instance is expected to receive name twice, or iftwo receives total are expected. (It's the former.)
Using this feature is often a design smell. It may be that your test is trying to do too much or that the object under test is toocomplex.
It is the most complicated feature of rspec-mocks, and has historically received the most bug reports. (None of the core teamactively use it, which doesn't help.)