在控制器中存储超级方法

时间:2014-10-08 19:12:46

标签: rspec super stub

如何存根:包含模块的超级方法。我有以下控制器:

class ImportsController < BaseController
   include ImportBackend

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

和importBackend模块:

module ImportBackend
  def import_from_file
    //something
  end
end

我想测试那个控制器。我的问题是如何在ImportBackend中存根方法来引发错误?我尝试了几种解决方案,但没有任何作用:

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)

感谢所有答案。

1 个答案:

答案 0 :(得分:8)

Ruby super中的

看起来像一个方法,但它实际上是一个具有特殊行为的关键字(例如,supersuper()执行不同的操作,与其他Ruby不同方法),你不能存根。

你真正想做的是存根super调用的方法,在这种情况下是ImportBackend#import_from_file。因为它是来自模块(而不是超类)的mixin,所以你不能以通常的方式将其存根。但是,您可以定义一个具有所需模拟行为的虚拟模块,并在您的类中include。这是有效的,因为当多个模块定义mixin时,super将调用包含的最后一个。你可以read more about this approach here。在你的情况下,它看起来像这样:

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

controller.singleton_class.send(:include, mock_module)

根据您的其他规格,这可能会引入一些拆解的并发症,但我希望它可以帮助您开始。