2

我正在关注 Michael Hartl 的 Rails 教程,并且有一个 RSpec 测试代码片段:

expect do
 click_button 'Follow'
end.to change(user.followed_users, :count).by(1)`

根据RSpec 文档以及我在Codeschool上的学习方式,这应该是:

expect do
 click_button 'Follow'
end.to change {user.followed_users.count}.by(1)

显然它们都是有效的,但似乎没有关于在 RSpec 文档中进行更改匹配器的第一种方法的文档,我想知道它为什么/如何工作。

4

2 回答 2

4

我在 Relish 文档中也找不到它,但 RSpec 毕竟是开源的,所以让我们深入研究一下。在当前版本的更改匹配器中

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自己。

于 2013-05-14T14:43:50.433 回答
0

rubydoc.info中的#change方法的文档。
它说明您可以使用块或receiverandmessage参数。您可以查看页面中提供的示例。

于 2015-01-26T15:45:28.310 回答