谁能解释为什么这个规范失败了?
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
最佳答案
问题是这一行:
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 语法
expect(UserPresenter).to receive(:new).once.and_call_original
参见 this有关期待消息的更多信息,以及 this有关调用原始方法的更多信息。 This对 RSpec 的 should_receive
方法有一些进一步的讨论。
关于ruby - 为什么这个 Ruby 条件赋值没有被内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23710331/