Как я могу высмеять супер в ruby с помощью rspec?
Я расширяю существующую библиотеку, создавая дочерний класс, который распространяется на класс библиотеки.
В дочернем классе я смог проверить большинство функций в методе initialize
, но не смог высмеять вызов super
. Детский класс выглядит примерно так.
class Child < SomeLibrary
def initialize(arg)
validate_arg(arg)
do_something
super(arg)
end
def validate_arg(arg)
# do the validation
end
def do_something
@setup = true
end
end
Как я могу написать rspec test (с моккой), чтобы я мог высмеивать вызов super
? Обратите внимание, что я тестирую функциональность метода initialize
в классе Child
. Должен ли я создавать отдельный путь кода, который не вызывает super
, когда ему предоставляется дополнительный аргумент?
Ответы
Ответ 1
Вы не можете высмеивать super
, и не должны. Когда вы что-то издеваетесь, вы проверяете, что получено определенное сообщение, а super
не является сообщением - это ключевое слово.
Вместо этого выясните, какое поведение этого класса изменится, если отсутствует вызов super
, и напишите пример, который выполняет и проверяет это поведение.
Ответ 2
Хорошим способом проверить это является ожидание некоторых действий, предпринятых суперклассом - пример:
class Some::Thing < Some
def instance_method
super
end
end
и суперкласс:
class Some
def instance_method
another_method
end
def self.another_method # not private!
'does a thing'
end
end
теперь тест:
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
Все это определяет, что супер был вызван над суперклассом
Эта полезность шаблона зависит от того, как вы структурируете свои тесты/какие ожидания у вас есть мутации типа "ребенок/производный" с помощью применяемого метода super
.
Кроме того, обратите внимание на методы class
и instance
, вам нужно будет отрегулировать allows
и expects
соответственно
YMMV
Ответ 3
Немного опоздал на эту вечеринку, но вы также можете отказаться от использования ключевого слова super
и вместо этого сделать
class Parent
def m(*args)
end
end
class Child < Parent
alias super_m m
def m(*args)
super_m(*args)
end
end
Таким образом, ваш супер метод доступен, как и любой другой метод, и может, например, быть заколотым как любой другой метод. Основным недостатком является то, что вы должны явно передавать аргументы для вызова метода super.