How can I mock super in ruby using rspec? How can I mock super in ruby using rspec? ruby ruby

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.)