RSpec matchers are a powerful tool. They allow you describe what your intentions are in a concise and accurate way.
However, like anything meant to be interpreted by a machine, they can become verbose.
Imagine we have a
Post class, which has a list of comments stored managed by some external service that we access over HTTPs.
We want to test that we call the API with the correct parameters. It’s a simple proposition, but the expectation can become a little unwieldy and repetitive.
Not terrible, but certainly a bit verbose and repetitive. We can do better.
In RSpec, the argument received by
.to is called a matcher. Matchers define the expectations for the behavior of the "subject" you are testing. Although "matchers" give you a nice syntax for describing what is being tested, they can quickly become procedural. In our example, a significant portion of the matcher is boilerplate and/or implementation details.
Luckily, RSpec gives you a way to define Custom Matchers; very exciting!
However, in my experience, people do not begin creating Custom Matchers until expectations get extremely unwieldy. It’s not because I do not like them, it is because I can never remember the syntax.
Luckily, matchers are easy to create. In fact, you create them for every spec. Since matchers are just encapsulated objects, you can name them!
So these days instead of writing a Custom Matcher, I define a plain-old Ruby Method (PORM?) which returns a matcher. If the matcher becomes useful enough that is justifies it’s own Custom Matcher, I will then extract it.
Now, our new spec now becomes:
Much simpler, eh?