具有多个参数的RSpec和自定义匹配器

Laz*_*dis 6 ruby rspec ruby-on-rails ruby-on-rails-3

我正在尝试使用RSpec为RoR中的测试创建自定义匹配器.

  define :be_accessible do |attributes|
    attributes = attributes.is_a?(Array) ? attributes : [attributes]
    attributes.each do |attribute|
      match do |response|
        response.class.accessible_attributes.include?(attribute)
      end
      description { "#{attribute} should be accessible" }
      failure_message_for_should { "#{attribute} should be accessible" }
      failure_message_for_should_not { "#{attribute} should not be accessible" }
    end
  end
Run Code Online (Sandbox Code Playgroud)

我希望能够在我的测试中编写类似下面的内容:

...
should be_accessible(:name, :surname, :description)
...
Run Code Online (Sandbox Code Playgroud)

但是使用上面定义的匹配器,我必须传递一个符号数组而不是用逗号分隔的符号,否则测试只会检查第一个符号.

有任何想法吗?

Saa*_*man 4

我让它这样工作:

RSpec::Matchers.define :be_accessible do |*attributes|
  match do |response|

    description { "#{attributes.inspect} be accessible" }

    attributes.each do |attribute|
      failure_message_for_should { "#{attribute} should be accessible" }
      failure_message_for_should_not { "#{attribute} should not be accessible" }

      break false unless response.class.accessible_attributes.include?(attribute)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我颠倒了match和 循环each。我认为这就是 Rspec 所期望的方式,因为赋予该match方法的块是由 Rspec 抽象匹配器执行的块(我猜)。

通过使用 定义块|*attributes|,它会获取参数列表并将其转换为Array.

所以打电话should be_accessible(:name, :surname, :description)就可以了。

顺便说一句,如果您只想检查属性是否存在,一个简单的方法

should respond_to(:name, :surname, :description)
Run Code Online (Sandbox Code Playgroud)

也有效。但它看起来并不像大规模分配方面。