如何在rspec中编写自定义MessageExpectation?

时间:2018-06-11 23:25:29

标签: ruby rspec

我有一个测试,我可以使用receive()编写带有自变量验证参数的块参数,如下所示:

expect(provider).to receive(:shell_out!) do |*args|
  expect(args.flatten.compact.map(&:to_s)).to eql(["useradd", "-m", "adam"])
end

我要编写数百个这样的测试,我想将其缩短为:

expect(provider).to receive(:shell_out!).with_flat_compact_str("useradd", "-m", "adam")

我目前正在使用自定义方法进行monkeypatching,以便将其实现到RSpec::Mocks::MessageExpectation课程中,我想知道是否有更简单的方法来获取我的内容要什么?

请注意,这样做的目的是shell_out!(*args) API将采用其splat args并对其运行args.flatten.compact.map(&:to_s),并且我希望允许对不会失败的消息设置期望如果调用者对调用进行了无关紧要的更改(即将shell_out!(a, b, c)shell_out!(a, nil, [b, c])视为相同。我也明确地不想使用一种方法调用它,然后在内部API调用之后设置期望splat已经正常化了。

另请注意,我试图编写一个看起来像这样的自定义匹配器:

receive(:shell_out).with(flat_compact_str("useradd", "-m", "adam"))

我发现的是,这与splat args不起作用(至少我无法弄明白)。如果有一个参数是一个数组,但不是所有的参数,它会工作。 Splat arg matchers在其中具有特殊的魔力。

1 个答案:

答案 0 :(得分:2)

鉴于子类化MessageExpectation可能会导致痛苦,最简单的方法是制作一个小的自定义帮助方法:

rgb

可以只包含在需要它的示例组中,也可以通过RSpec配置块包含所有组。