Следует ли делать то, чего я не ожидаю?
Рассмотрим следующие две тривиальные модели:
class Iq
def score
#Some Irrelevant Code
end
end
class Person
def iq_score
Iq.new(self).score #error here
end
end
И следующий тест Rspec:
describe "#iq_score" do
let(:person) { Person.new }
it "creates an instance of Iq with the person" do
Iq.should_receive(:new).with(person)
Iq.any_instance.stub(:score).and_return(100.0)
person.iq_score
end
end
Когда я запускаю этот тест (или, скорее, аналогичный), кажется, заглушка не работает:
Failure/Error: person.iq_score
NoMethodError:
undefined method `iq_score' for nil:NilClass
Ошибка, как вы можете догадаться, находится на строке с пометкой "ошибка здесь" выше. Когда should_receive
строка закомментирована, эта ошибка исчезает. В чем дело?
2 ответа
Решение
Вы удаляете инициализатор:
Iq.should_receive(:new).with(person)
возвращает ноль, поэтому Iq.new - ноль. Чтобы исправить, просто сделайте это:
Iq.should_receive(:new).with(person).and_return(mock('iq', :iq_score => 34))
person.iq_score.should == 34 // assert it is really the mock you get
Поскольку RSpec имеет расширенные функциональные возможности стаббера, теперь следующий способ верен:
Iq.should_receive(:new).with(person).and_call_original
Он будет (1) проверять ожидание (2) возвращать управление исходной функции, а не просто возвращать ноль.