2

出于测试原因,我最近移动了一些 RSpec 匹配器以使用类形式而不是 DSL。当它们采用这种形式时,有没有办法轻松获得链接行为。

例如

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

非常感谢

4

1 回答 1

4

添加一个名为 chain 的新方法,通常应该返回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')

这样做的原因是您正在构建要传递给shouldorexpect(object).to方法的对象。然后这些方法调用matches?提供的对象。

所以它与其他 ruby​​ 代码(如puts "hi there".reverse.upcase.gsub('T', '7'). 这里的字符串"hi there"是你的匹配器,并在其上调用链式方法,传递从gsubto返回的最终对象puts

内置的期望change匹配器是一个很好的例子。

于 2013-05-02T13:30:11.907 回答