2013-04-21 47 views
5

我想在使用RSpec的RoR中测试创建一个自定义匹配器。具有多个参数的RSpec和自定义匹配器

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 

我希望能够写出像在我的测试如下:

... 
should be_accessible(:name, :surname, :description) 
... 

但与上述定义的匹配,我必须通过符号的阵列,而不是分隔符号逗号,否则测试只检查第一个符号。

任何想法?

+0

下面是一个应该匹配你的第一个需要的答案:http://stackoverflow.com/a/4643289/582863。无论如何,我对你的意图很好奇......你只是想减少你的rspec测试文件中的行数,还是测试你的模型属性的复杂可访问性? – Saaman 2013-04-21 21:44:32

+0

你提供的链接的问题是,这不是一个“常规”的def方法,所以我不能使用*。回答你的问题,我只是想减少我的rspec的线:) – 2013-04-21 21:51:44

回答

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 

我倒了matcheach环。我认为这是Rspec期望它的方式,因为给予match方法的块是由Rspec抽象匹配器执行的块(我猜)。

通过使用|*attributes|定义块,它将参数列表变为Array

所以打电话should be_accessible(:name, :surname, :description)将工作。

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

should respond_to(:name, :surname, :description) 

工作为好。但它看起来不像大众分配方面。

+0

它的工作原理,thanx你的时间!我想检查质量分配,因此您的解决方案就是我需要的解决方案。 – 2013-04-22 10:34:11

+0

然而,这真的对我有帮助,当我根据自己的情况调整这个例子时,我发现它只适用于积极的期望(不适用于should_not原样)。我必须创建单独的'match_for_should'和'match_for_should_not'块,如下所示:https://www.relishapp.com/rspec/rspec-expectations/v/3-0/docs/custom-matchers/define-matcher#matcher -with-单独逻辑换应和 - 应该-不 – manafire 2014-01-02 06:56:35

相关问题