Это довольно интересная проблема.Быстрое решение состоит в том, чтобы просто заменить блочную форму Comment.stub
:
Comment.stub(:find).with("12") { mock_comment(:update_attributes => false) }
на явную and_return
:
Comment.stub(:find).with("12").\
and_return(mock_comment(:update_attributes => false))
Почему эти две формы должны давать разные результатыЭто немного головокружение.Если вы поэкспериментируете с первой формой, то увидите, что mock на самом деле возвращает self
вместо false
при вызове метода-заглушки.Это говорит нам о том, что он не заглушил метод (поскольку он указан как нулевой объект).
Ответ заключается в том, что при передаче в блоке блок выполняется только при вызове метода с заглушкой, а не когдазаглушка определена.Поэтому при использовании блочной формы следующий вызов:
put :update, :post_id => mock_comment.post.id, :id => "12"
выполняется mock_comment
в первый раз.Поскольку :update_attributes => false
не передается, метод не заглушается, и вместо false
возвращается mock.Когда блок вызывает mock_comment
, он возвращает @mock_comment
, в котором нет заглушки.
Наоборот, использование явной формы and_return
вызывает mock_comment
немедленно.Вероятно, было бы лучше использовать переменную экземпляра вместо вызова метода каждый раз, чтобы сделать намерение более понятным:
it "re-renders the 'edit' template" do
mock_comment(:update_attributes => false)
Comment.stub(:find).with("12") { @mock_comment }
put :update, :post_id => @mock_comment.post.id, :id => "12"
response.should render_template("edit")
end