Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stub super method in controller

Tags:

super

stub

rspec

How to stub :super method from included module. I have following controller:

class ImportsController < BaseController
   include ImportBackend

  def import_from_file
    super
  rescue TransferPreview::Error => exc
    flash[:error] = "Some String"
    redirect_to imports_path
  end
end

And importBackend module:

module ImportBackend
  def import_from_file
    //something
  end
end

I want to test that controller. My question is how to stub method in ImportBackend to raise error? I tried couple solutions but nothing works:

ImportBackend.stub(:import_from_file).and_raise(Transfer::Error)
controller.stub(:super).and_raise(Transfer::Error)
controller.stub(:import_from_file).and_raise(Transfer::Error)

Thanks for all answers.

like image 487
user2239655 Avatar asked Oct 08 '14 19:10

user2239655


1 Answers

in Ruby super looks like a method, but it's actually a keyword with special behavior (for example, super and super() do different things, unlike every other Ruby method), and you can't stub it.

What you really want to do is stub the method that super invokes, which in this case is ImportBackend#import_from_file. Since it's a mixin from a module (and not a superclass) you can't stub it in the usual way. You can, however, define a dummy module that has the mock behavior you want, and include it in your class. This works because when multiple modules define a mixin, super will invoke the last one included. You can read more about this approach here. In your case, it would look something like this:

mock_module = Module.new do
  def import_from_file
    raise Transfer::Error
  end
end

controller.singleton_class.send(:include, mock_module)

Depending on your other specs, this could introduce some complications with teardown, but I hope it helps get you started.

like image 176
Jordan Running Avatar answered Dec 01 '22 00:12

Jordan Running