2013-05-02 112 views
2

由於測試的原因,我最近移動了一些RSpec匹配器來使用類形式而不是DSL。當他們處於這種形式時,是否可以輕鬆獲得鏈式行爲?鏈接Rspec自定義匹配器

E.g.

class BeInZone 
    def initialize(expected) 
    @expected = expected 
    end 
    def matches?(target) 
    @target = target 
    @target.current_zone.eql?(Zone.new(@expected)) 
    end 
    def failure_message 
    "expected #{@target.inspect} to be in Zone #{@expected}" 
    end 
    def negative_failure_message 
    "expected #{@target.inspect} not to be in Zone #{@expected}" 
    end 
    # chain methods here 
end 

非常感謝

+0

你可以給你一個你想能夠做的鏈式方法調用的例子嗎? – 2013-05-02 13:28:14

回答

3

添加一個新的方法與鏈的名稱,一般應返回self。通常你保存提供的鏈接狀態。然後您更新matches?方法以使用。這個狀態也可以在各種輸出消息方法中使用。

因此,對於你的例子:

class BeInZone 
    # Your code 

    def matches?(target) 
    @target = target 

    matches_zone? && matches_name? 
    end 

    def with_name(name) 
    @target_name = name 
    self 
    end 

    private 
    def matches_zone? 
    @target.current_zone.eql?(Zone.new(@expected)) 
    end 

    def matches_name? 
    true unless @target_name 

    @target =~ @target_name 
    end 
end 

然後使用它:expect(zoneA_1).to be_in_zone(zoneA).with_name('1')

這部作品的原因是,你正在建設要傳遞到要麼shouldexpect(object).to方法的對象。這些方法然後在提供的對象上調用matches?

因此,它與其他類似puts "hi there".reverse.upcase.gsub('T', '7')的ruby代碼沒有區別。這裏字符串"hi there"是你的匹配器,並且鏈接的方法被調用,將從gsub返回的最終對象傳遞給puts

匹配器的內置預期change是一個很好的例子來審查。

+0

很感謝。將更新我的匹配器。 – 2013-05-02 14:21:08