RSpec'改变':大括号还是括号?

时间:2013-05-14 14:35:15

标签: ruby-on-rails ruby rspec

我正在关注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文档中进行更改匹配的第一种方法的文档,我想知道它为什么/如何工作。

2 个答案:

答案 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了解 ruby​​doc.info。中的 #change 方法 它解释了您可以使用块或receivermessage参数。您可以查看页面中提供的示例。