出于测试原因,我最近移动了一些RSpec匹配器来使用类形式而不是DSL。有没有办法在这种形式下轻松获得链接行为。
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 :(得分:3)
添加一个名为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')
这样做的原因是您正在构建要传递给should
或expect(object).to
方法的对象。然后,这些方法在提供的对象上调用matches?
。
所以它与其他红宝石代码如puts "hi there".reverse.upcase.gsub('T', '7')
没什么不同。在这里,字符串"hi there"
是您的匹配器,并在其上调用链接方法,将从gsub
返回的最终对象传递给puts
。
内置的期望change
匹配器是一个很好的例子。
答案 1 :(得分:0)
我写了一篇关于这个主题的教程
请参阅: www.danielcsite.com/rspec_custom_matchers
在本教程中,我将详细介绍并使用屏幕截图如何编写自定义匹配器类并通过链接多种方法来调用它。