Failure messages for compound expectations inside custom matchers

32 views
Skip to first unread message

Kerry Buckley

unread,
Feb 1, 2015, 5:17:43 AM2/1/15
to rs...@googlegroups.com
I've recently discovered compound expectations in RSpec 3, which I really like, but I noticed a difference in output if you use them within a custom matcher. For example:

RSpec::Matchers.define :be_acceptable do
  match do |actual|
    expect(actual).to be_even.and be > 10
  end
end

describe "Composing matchers" do
  it "works in an expectation" do
    expect(1).to be_even.and be > 10
  end

  it "works inside another matcher" do
    expect(1).to be_acceptable
  end
end

Both expectations work, but the second loses the detailed failure information:

Failure/Error: expect(1).to be_even.and be > 10 expected `1.even?` to return true, got false ...and: expected: > 10 got:   1 
Failure/Error: expect(1).to be_acceptable expected 1 to be acceptable

Is there a way to encapsulate a set of other matchers inside another matcher, while retaining the full failure messages?

Thanks,

Kerry

Myron Marston

unread,
Feb 1, 2015, 10:47:39 AM2/1/15
to rs...@googlegroups.com

By defining a custom be_acceptable matcher, you are telling RSpec you want the description and failure message to use “be acceptable” in the description and failure message.

OTOH, if you simply want to use be_acceptable, and don’t care about it actually being a custom matcher, you can define it simply as a well-named helper method that returns the compound matcher expression:

module MatcherHelpers
  def be_acceptable
     be_even.and be > 10
  end
end

RSpec.configure do |c|
  c.include MatcherHelpers
end

…which will give you the exact same failure as your first example.

HTH,
Myron

 

Kerry Buckley

unread,
Feb 9, 2015, 4:21:22 PM2/9/15
to rs...@googlegroups.com
On Sunday, 1 February 2015 15:47:39 UTC, Myron Marston wrote:

By defining a custom be_acceptable matcher, you are telling RSpec you want the description and failure message to use “be acceptable” in the description and failure message.

OTOH, if you simply want to use be_acceptable, and don’t care about it actually being a custom matcher, you can define it simply as a well-named helper method that returns the compound matcher expression:

module MatcherHelpers
  def be_acceptable
     be_even.and be > 10
  end
end

RSpec.configure do |c|
  c.include MatcherHelpers
end

…which will give you the exact same failure as your first example.

Thanks Myron – looks like I was trying to make things too complicated! Sorry for not replying earlier, but apparently Google Groups had decided not to mail me updates for the thread for some reason.

Kerry
Reply all
Reply to author
Forward
0 new messages