Супер способ заглушки в контроллер
Как заглушить: супер метод из включенного модуля. У меня есть следующий контроллер:
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 ответ:
В Ruby
Что вы действительно хотите сделать, так это заглушить метод, который вызываетsuper
выглядит как метод, но на самом деле это ключевое слово со специальным поведением (например,super
иsuper()
делают разные вещи, в отличие от любого другого метода Ruby), и вы не можете заглушить его.super
, который в данном случае являетсяImportBackend#import_from_file
. Поскольку это микшер из модуля (а не суперкласса), вы не можете заглушить его обычным способом. Вы можете, однако, определить фиктивный модуль, который имеет макет поведения, которое вы хотите, иinclude
он в вашем класс. Это работает потому, что когда несколько модулей определяют mixin,super
вызовет последний включенный. Вы можете прочитать больше об этом подходе здесь. В вашем случае это выглядело бы примерно так:mock_module = Module.new do def import_from_file raise Transfer::Error end end controller.singleton_class.send(:include, mock_module)
В зависимости от ваших других спецификаций, это может привести к некоторым осложнениям с teardown, но я надеюсь, что это поможет вам начать.