有人可以解释为什么这个规范失败了吗?
RSpec结果:
User#presenter memoizes presenter
Failure/Error: user.presenter
(<UserPresenter (class)>).new(...)
expected: 1 time with any arguments
received: 2 times with arguments: (...)
根据我对条件赋值运算符的理解,它应该只分配@presenter
一次。
# app/models/user.rb
def User
def presenter
@presenter ||= UserPresenter.new(self)
end
end
# app/presenters/user_presenter.rb
class UserPresenter
end
# spec/models/user_spec.rb
describe User do
let(:user){ build_stubbed(:user) }
describe "#presenter" do
it "memoizes presenter" do
UserPresenter.should_receive(:new).once
user.presenter
user.presenter # should not call .new
end
end
end
答案 0 :(得分:1)
问题是这一行:
UserPresenter.should_receive(:new).once
这段代码只是设置了UserPresenter
一次接收new
方法的期望。它会删除原始的UserPresenter#new
方法,并将其替换为返回nil
的方法。由于nil
是假的,因此@presenter
实例变量不会被记忆。
要解决此问题,您可以指定期望值的返回值:
UserPresenter.should_receive(:new).once.and_return "some truthy value"
或等效
UserPresenter.should_receive(:new).once { "some truthy value" }
或者如果您绝对想要调用原始方法
UserPresenter.should_receive(:new).once.and_call_original
或使用新的期望语法
expect(UserPresenter).to receive(:new).once.and_call_original
有关预期消息的详细信息,请参阅this;有关调用原始方法的详细信息,请参阅this。 This对RSpec的should_receive
方法进行了进一步的讨论。