我正在关注Michael Hartl的Rails教程,并且有一个RSpec测试代码片段:
expect do
click_button 'Follow'
end.to change(user.followed_users, :count).by(1)`
根据RSpec documentation以及我在Codeschool上的了解情况,这应该是:
expect do
click_button 'Follow'
end.to change {user.followed_users.count}.by(1)
显然它们都是有效的,但似乎没有关于在RSpec文档中进行更改匹配的第一种方法的文档,我想知道它为什么/如何工作。
答案 0 :(得分:4)
我也没能在Relish文档中找到它,但RSpec毕竟是开源的,所以让我们深入研究。在the current version of the change matcher:
module RSpec
module Matchers
module BuiltIn
class Change
def initialize(receiver=nil, message=nil, &block)
@message = message
@value_proc = block || lambda {receiver.__send__(message)}
@expected_after = @expected_before = @minimum = @maximum = @expected_delta = nil
@eval_before = @eval_after = false
end
关于@value_proc
的全部内容。如果你提供一个块,它会使用它;如果你不提供一个块,它会创建一个新的lambda,它将第二个参数发送给第一个参数。如果您仔细阅读了源代码,您会看到#matches?
方法,其中包含:
@actual_before = evaluate_value_proc
event_proc.call
@actual_after = evaluate_value_proc
其中evaluate_value_proc
主要是@value_proc.call
。
我认为“常规”RSpec会让你提供一个明确的块。如果你是元编程,那么双参数方法可能更有意义,但即使这样,你也可以使用块方法并自己调用send
。
答案 1 :(得分:0)
Documentation了解 rubydoc.info。中的 #change 方法
它解释了您可以使用块或receiver
和message
参数。您可以查看页面中提供的示例。