在 rspec 自定义匹配器中重新使用失败消息

Re-use failure message in rspec custom matcher

我有一个自定义匹配器,在它的匹配块中使用了 expects(此处的代码已简化)

RSpec::Matchers.define :have_foo_content do |expected|
  match do |actual|
    expect(actual).to contain_exactly(expected)
    expect(actual.foo).to contain_exactly(expected.foo)
  end
end

通常错误信息是这样的

       expected collection contained:  ["VLPpzkjahD"]
       actual collection contained:    ["yBzPmoRnSK"]
       the missing elements were:      ["VLPpzkjahD"]
       the extra elements were:        ["yBzPmoRnSK"]

但是当使用自定义匹配器时,它只打印这个,重要的调试信息丢失了:

expected MyObject to have_foo_content "foobar"

那么,是否可以将匹配块中的错误消息重新用作失败消息?我知道我可以提供自定义失败消息

failure_message do |actual|
  # ...
end

但我不知道您如何访问上述错误引发的失败消息。

没有直接的方法可以产生原始错误,我建议您编写自己的逻辑来生成类似的消息。

如果您仍想使用现有方法,可以调用一个私有方法,它将 return 默认错误消息。您可能需要设置一些实例变量expected_valueactual_value

RSpec::Matchers::BuiltIn::ContainExactly.new(expected_value).failure_message

reference code

您可以在 match 中拯救 RSpec::Expectations::ExpectationNotMetError 以捕获失败的期望消息:

  match do |object|
    begin
      expect(object).to be_nil
    rescue RSpec::Expectations::ExpectationNotMetError => e
      @error = e
      raise
    end
  end

  failure_message do
    <<~MESSAGE
      Expected object to meet my custom matcher expectation but failed with error:
      #{@error}
    MESSAGE
  end

不要忘记在rescue中再次加注,否则不会成功