PHPUnit: Making your own assertion
Callbacks, callbacks, constraint, callbacks
Even so, PHPUnit is not perfect, and for your project, you may need a “custom” assertion. For example, I just stumbled upon the need to create a simple assertion to check if a class extending other contains a given variable set of methods.
There is no
assertMethodExists for PHPUnit, so you may want to use
This will suffice, but there is another, more elegant way: creating your own.
The way most assertions work in PHPUnit is relatively simple. The base PHPUnit class,
Assert, which is extended by
TestCase, contains the
assertThat() method. This method is called by other assertions with the value, an “expectation” class, and the message to return when the expectation fail.
The expectation object is a class extending the
Constraint. This allows to receive the value and do multiple checks on it, making assertion more flexible instead of hard coding comparisons.
As you are already guessing, we can create our own Constraint, but there is mostly not need to do it. There are already some constraints like
IsEmpty, and many others, that are easily created using the method of the same name.
Using an existing Constraint
What I’m looking for is to check if
true for a given class and method. I can borrow the
IsTrue constraint, which doesn’t take any argument, to be compared with what the method returns.
The same thing can be achieved using
assertTrue(), but to me this feels more declarative. But where not here for this simple thing.
Using a callback
Let’s make the assumption that I need to assert that a method has a return type for a given class. Instead of creating a class that extends
Constraint, we can use the
Callback constraint which will save us time.
This callback receives the value, which in this case is an object instance, and must return
For more complex scenarios, we may need to create a
Constraint instance, but that’s when the scope of a callback is way below what we want to assert. You may want to use that approach of creating your own Constraint if you want to avoid having traits or classes full of callbacks.
Bonus tip: Failing
You may thing that a callback must return a boolean, and that you’re married to return whatever message
assertThat has set in case the assertion fails. Luckily, that is not the case. You can use the
fail() method to fail an assertion manually, even inside a callback.
Following the above example, let’s say we want to return a message saying that the method does not exist. No problem, we will induce
fail() if the
For extensively larger logic around assertion, don’t by shy and extend the
Constraint class of PHPUnit with your own.