Следует ли делать то, чего я не ожидаю?

Рассмотрим следующие две тривиальные модели:

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) возвращать управление исходной функции, а не просто возвращать ноль.

Другие вопросы по тегам