PHPUnit: Self-testing your new custom assertion
Who tests the testmen?
When testing your code, PHPUnit is basically the hero. Creating tests is plain easy. It’s all bells and whistles until you start to see a repeated set of assertions in a lot of tests. Then you start to think about creating a method to group them.
Okay, the latter is a good quick solution, but often I find myself looking for a more elegant one, like creating a custom assertion with a more descriptive message for the data being asserted. So instead of failing a bunch of assertions, the custom assertion is in charge of all of that.
What is a Custom Assertion?
A custom assertion is basically a method that will test if the given data is valid depending on what you consider. So, for example, we can consider that a JSON data is valid is it complies with a structure, and the values are of certain type.
As PHPUnit 8.0 says, you can just create a new assertion by creating an abstract class that extend the base
TestCase. Sounds good, but if you have multiple assertions, it’s just better to have an abstract class including traits, or including these traits into your Testing Class, rather than putting everything into one file.
So, for that matter, I will create a custom
assertJsonData assertion, that will check if the JSON complies with the structure, and values. It’s very simple, and it uses the built-in assertions in PHPUnit.
Okay, the new assertion is now complete. Now, how we can test this assertion to be sure it works as intended? Well, we can check out how PHPUnit tests itself.
As you can see, the failed test basically expects the
AssertionFailedError being thrown. We can replicate that in our next step: create a new Test to check if the assertion not only asserts a correct value, but also fails when its not.
Since our new assertion can fail at multiple points, we need to create a failure for these specific parts of our code.
With that, not only we have created our own assertion, even using the already innards of PHPUnit assertions, but also tested if it fails when it should. With some magic of the @expectedexceptionmessage of PHPUnit, we can also test the message being returned by the
If you need more complex logic, you can always create your own Constraint. These classes can test more thoroughly a given condition. You should check the documentation about extending PHPUnit with your own testing.
You may think this is kind of overkill for a simple assertion, but for to large or complex ones, it may become very handy since you can test if the assertion works as intended, which could save some headaches when the assertion fails or succeeds when it shouldn’t.