2013-05-02 80 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