Unit Testing XVI - Wrapup

A review and evaluation of the series on unit testing and a preview of code coverage

In the previous article in this series, we saw the User4.class.php used with our T5_UserMockingTest to demonstrate testing expectations about how often a method will be called. In this one, we'll review our progress through the various unit tests and discuss some of the issues we encountered.

MODX logo


Unit testing tests the smallest units of a project in isolation — usually individual classes and their methods. We started with a simple test to make sure the Codeception and PhpUnit packages were working. In keeping with the concept of Test-driven Development (TDD), we created our tests, then added the code that would pass them.

Next, we moved on to testing the User class constructor and validating the User class fields. Then we added some error handling and tested it.

We extracted our validation code to a separate Validator class (after creating tests for it using a data provider).

Finally, we discussed Dependency Injection (DI) and used it to pass a stubbed version of our Validator class into our User class.

Along the way, we saw some bad code, and some bad design. I hope you'll forgive the missteps we took in the process. As I said in an earlier article, it's my belief that you can learn at least as much from bad examples as you can from good ones. In fact, it's time to reveal that our User class is still flawed.

What should really happen is that the validation of the User class fields should take place before the User class is ever involved. It should happen in a controller or in the code that processes a form submitted by the user. It could use our Validator class for that, so creating the Validator class and the tests of it wasn't a complete waste of time.

Validating the fields ahead of time would simplify the User class constructor so that all it does is set the user fields and save the user.

We didn't do that for two reasons. The first is that we wouldn't have been able to show many of the various testing techniques in the previous articles. Our tests of the User class would have been so simple that there wouldn't be much to learn from them. The second reason is that testing the interaction of the form and the User class would have involved "integration testing," which we'll look at in future articles in this series. Fully testing the User class save() function would also involve integration testing, which is why we didn't bother to create any tests for it.

Code Coverage

As you read the previous articles, you may have noticed some tests that could (or should) have been performed because there was code in our classes that would never be executed in our tests. Rather than reading through all the code looking for them, we can use a very sophisticated PhpUnit add-on that measures Code Coverage. We'll take a closer look at that in the following articles.

Coming Up

In the next article, we'll see how to set up Codeception to produce code coverage reports.


For more information on how to use MODX to create a web site, see my web site Bob's Guides, or better yet, buy my book: MODX: The Official Guide.

Looking for high-quality, MODX-friendly hosting? As of May 2016, Bob's Guides is hosted at A2 hosting. MODX will work fine at most hosting services, but having a MODX-friendly host can prevent a lot of frustration. Better yet, the A2 Solid-State-Drive servers are configured to handle the many Ajax and database calls made by MODX — especially the MODX Manager. My Manager runs about four times as fast as it did on my previous host. I particularly recommend the Swift package with the Performance Plus option.

Comments (0)

Please login to comment.