#ruby #rspec #rspec-mocks
#ruby #rspec #rspec-издевается
Вопрос:
Я пытаюсь отключить глобальную функцию, вызываемую из конструктора. Я использую Rspec и Rspec-mocks. Вот код для тестирования:
def foo
'foo'
end
class Bar
def initialize
@bar = foo
end
def bar
@bar
end
end
И вот тест:
describe 'bar'
it 'calls foo' do
expect(self).to receive(:foo) { 'bar' }
expect(Bar.new.bar).to eq('bar')
end
end
Тест завершается ошибкой со следующим сообщением:
Failure/Error: expect(Bar.new.bar).to eq('bar')
expected: "bar"
got: "foo"
(compared using ==)
Как я могу отключить глобальную функцию? foo
PS: expect(self).to receive(:foo) { 'bar' }
работает должным образом, если foo
вызывается из другой глобальной функции.
Ответ №1:
Вероятно, самым простым решением является uses #allow_any_instance_of
, которое работает, потому что «глобальные» функции на самом деле Kernel
являются методами в Ruby. Но поскольку документация не рекомендует заглушать классы глобально, я подумал, что, по крайней мере, предложу альтернативу:
def foo
'foo'
end
class Bar
def self.get_foo
foo
end
def initialize
@bar = self.class.get_foo
end
def bar
@bar
end
end
и
describe Bar do
it 'gets foo' do
expect(Bar).to receive(:get_foo).and_return('bar')
expect(Bar.new.bar).to eq('bar')
end
end
Конечно, если возможно, было бы лучше отказаться от Kernel
метода и просто использовать метод класса.
Ответ №2:
allow_any_instance_of(Bar).to receive(:foo) { 'bar' }