Automating Unit TestingPHPUnit and Refactoring for Dependency Injection |
In preparation for the creation of a DevOps workflow for deployment, PHPUnitA PHP Library for Code Test Automation was added to the project to automate unit and integration tests. The Udemy class “Introduction to Testing with PHPUnitA PHP Library for Code Test Automation” recommended the dependency injection design pattern to make it easier to test individual units by mocking all class dependencies. Additionally, a number of articles noted the difficulties of testing static functions. The classes that call them are tightly coupled to these static functions and as a result, they cannot be mocked, making it impossible to unit test the calling class independently.
As there were classes in the original code that were comprised entirely of static functions it was necessary to refactor much of the code. The Auryn InjectorA PHP Dependency Injector library to support Inversion of Control design pattern. was introduced to the project to support dependency injection. Additionally, XDebugA PHP extension which provides debugging and profiling capabilities. was installed to allow code coverage to be analyzed and reported.
This turned out to be a much more invasive project than I imagined. An attempt was made to exhaustively unit test the code, however, I have mixed feelings about the value of such tests. The major advantage is that it forces you to write code so that can be unit tested which makes it easier to isolate the code of a class by mocking and stubbing the other classes that may be referenced. However, after mocking all the dependencies the tests feel somewhat useless and do little to increase confidence in the code. The code written for testing ended up being significantly larger than the application code itself.
Integration tests were of much greater value and I may revise my approach to limit strict unit testing going forward while continuing to write code that would allow unit tests to be performed if desired.