2013-04-21 93 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

相關問題