Using a Custom RSpec Matcher with RSpec mocks


I wanted to check whether a value has been passed to a mock in my code, the solution seems simple using the with method. I have isolated the bit I am interested in to reduce the noise.

def save!(document)

For the test I would normally I would use the standard with method and pass the expected value.


However my expected object contains a Date. As the with method calls the == the comparisson fails.

The documentation includes lots of examples I could use like kind_of(Class) or anything() but then I'm not testing much.

Custom Matchers.

As the with method accepts any RSpec Matcher, a custom matcher solves the problem.

At the top of the file add a custom matcher that checks the document_id is the same in the actual and expected object and that the created and updated times are within the last 60 seconds.

RSpec::Matchers.define :other_document do |expected|
  match do |actual|
    actual.user_id == expected.user_id &&
      actual.document_id == expected.document_id &&
      actual.created.between?( - 60,
      actual.updated.between?( - 60,

We can then use the custom matcher in our mock expectation


Which then passes ✅

© Peter Grainger.RSS