Here's an example from a public project of a (fairly basic) RSpec custom matcher that wraps an instance of a class that "does the real work"; what's in the actual matcher is mostly the "syntactic sugar" needed for it to play nice with the rest of RSpec.
This was in response to a comment thread on Reddit discussing the question, "Multiple assertions in a test, bad practise?" I want to express my appreciation to /u/jrochkind
for his response to my initial comment (that led to my responding to him, that led to a far better approximation of Enlightenment).
The matcher, as I said, is pretty basic:
- A
match
block instntiates aSavedEntityVerifier
class with the source and actual values for the expectation; specifies which fields in an entity are required in thesource
, theactual
, or both, and calls that instance's#reasons
method to get the validation error messages (if any); - A
description
block does just what it says on the tin, explaining what the significance of thesource
vsactual
objects is; and - A
failure_message
block lists out all the detected reasons why the verification failed, with the description as preamble.
Bear in mind that not all of our custom matchers wrap classes like this, but we're starting to encourage it as an internal convention. Which turns out to be fortuitous, because now, it's ridiculously easy to support not just RSpec, but any matcher's "syntactic sugar" using methods on the class being wrapped. This is the epiphany that /u/jrochkind
pushed me into.
Thoughts?