There was a time, back when I was working with PHP 5, when I found the Standard PHP Library (SPL) an extremely powerful and useful toolbox; and I particularly enjoyed working with SPL’s Iterators and Datastructures. Sadly, SPL was always a somewhat forgotten component of PHP, even when it was incorporated into core, probably due to the lack of documentation (although Pete Cowburn and the other PHP documentors did work hard to improve it over the years). With the arrival of PHP 7, SPL seems to have dropped even further into a backwater: generally we create our own exception classes, though we may sometimes use those in the SPL; we rely on Composer to handle autoloading, rather than using SPL directly to set up our autoloading manually; and Datastructures (one of my favourite SPL components) are better implemented in Rudi Theunissen’s ext-ds library.
But although much of the SPL is now outdated, or has been superseded by better language elements; some components are still useful. SPL’s Iterators are confusingly named, and there’s little in the documentation that explains when and how they can/should be used, but if you can learn to understand them, they are still powerful tools even with PHP 7; especially as they work with any Traversable (like Iterators and Generators, or the Collection objects provided by many frameworks), not simply with arrays.
I’m always nervous when I speak at a conference or in front of a user group; but I also enjoy sharing my passion and excitement for things that I’ve learned, or new tools that I’ve discovered. That makes it particularly difficult for me to withdraw from a conference where I’ve already committed to speak, not giving just one talk, but two. But sometimes it is necessary to stand by my beliefs, despite the fact that it causes disruption to the conference organisers when they’ve already announced the schedule, and means that I can’t share my passion for coding with the attendees at that conference.
That’s the position that I found myself in barely a week ago.
At New Year, many people write a retrospective of the old year, and about their hopes and dreams for the new.
The roots for my own changes over the last year really lie earlier: 2017 was the year when a health scare saw me rattling around the PHPNW Conference spaced out on a cocktail of drugs as the doctors tried to figure out what was wrong with me. My memories of the Conference are very fragmented, and the medics never did figure out the problem: fortunately my body resolved the situation (whether assisted by the drugs or not); although I spent much of that last Christmas/New Year period in agony from the side effects of some of the medications that I’d been prescribed.
But mentally at the beginning of 2018 I was also in a really bad state.
I’ve written before about the benefits of using PHP’s Anonymous Classes for test doubles; but Anonymous Classes also have potential usecases within production code as well. In this article I’m going to describe one such usecase that can be particularly useful within libraries, and that is replicating the access of Package Private (in Java), or Protected Internal Classes (as per C#).
In Java, a Package Private class will be accessible to other classes in the same package but will be inaccessible to classes outside the package, meaning that it isn’t possible to create an object of that class or to declare a variable of that class type. In C#, Internal or Protected Internal Classes enable a group of components to cooperate in a private manner without being exposed to the rest of the application code. Access to Internal Classes is limited to the assembly in which they exist, or can be granted to specific “friend” assemblies.
This class visibility simply in’t available in PHP, but it could be useful for library writers to have that control over visibility of the classes inside their packages that are only intended for internal use.
In the first article in this series, I wrote about the problems with testing static methods in classes, and showed a few approaches that allow us to write mocks for statics. Testing classes where we have static properties is a lot harder to manage, because any changes made in any test to those properties are global, across the entire test suite, not simply the test that we are running. Static properties are part of the global state, and we can’t simply
tearDown() those changes in the way that we do with instances — at least we cannot easily do so if the property has a visibility of private or protected.
Posted in PHP
Tagged PHP, Static, Testing
If you’ve read my previous post (Discharging Static #1), then you’ll know that recently I’ve been exploring different approaches to creating test doubles for statically called methods, and other testing problems, and had begun to look at Michael Bodnarchuk’s AspectMock library as an alternative to Mockery. Much as I like Mockery, and have no issues with it when tests are run standalone, it can be problematic when running the whole test suite; whether upstream tests have already autoloaded the classes that you need to mock, or breaking downstream tests, even when calling
Mockery::close() as part of the PHPUnit
AspectMock is a stubbing/mocking library written as part of the Codeception test framework, but which will also work with PHPUnit; and which provides functionality that not only allows mocking of both static and instance methods, but can also mock functions (including PHP’s built-in functions, as well as userland functions). It can achieve all this because it is built on the The Go! AOP framework for PHP. Exploring how this worked introduced me to the AOP (Aspect Oriented Programming) paradigm; and I feel like I’ve taken the red pill, followed the white rabbit down the hole, and entered the surreality of Wonderland.
Posted in PHP
Tagged AOP, Aspect, Go!, PHP
It’s been seven years since Kore Nordmann first published “static considered harmful” on his blog, explaining the problems with using static method calls in classes, and the difficulties that they cause when trying to test that class. Seven years on, and those difficulties are still the same, and there is still new code being written using static calls despite that knowledge; but it’s often a more severe problem in legacy code with little or no unit tests.
So why exactly are static calls so bad? If you’ve read Kore’s article, then you probably have a good idea already; but what that article doesn’t cover is approaches that we can use to make the code testable.
Posted in PHP
Tagged PHP, Static, Testing
In a prior article in this series, I described the use of a SpyMaster Class to create proxy spies as anonymous classes, that allow external visibility (and potentially update) of protected and private properties within an object. The same basic principle of a spy can also be used to create a proxy that gives us access to execute the private and protected methods of an object.
Why might we want to do this? One possible reason is that it gives us the ability to test the internal methods of an object in isolation from other code within the public methods that we would normally test.
We know that we should always write unit tests for our code, and mock dependencies; but that isn’t always easy when we need to mock classes define as
final, or that contain final methods. This isn’t normally a problem when we’re only working with classes within our own libraries and applications, because we control whether they are final or not, and we can type-hint these dependencies to interfaces. However, when the dependencies that we use are from external libraries, we lose that control; and it can become harder to test our own classes if we do need to mock final classes adn they haven’t been built to interfaces.
Libraries like Mockery do provide a proxy approach to mocking final Classes, which works well, but with one major limitation.
In a compromise between mocking functionality and type safety,
Mockery does allow creating "proxy mocks" from classes marked
final, or from classes with methods marked final. This offers
all the usual mock object goodness but the resulting mock will
not inherit the class type of the object being mocked, i.e. it
will not pass any instanceof comparison.
Unfortunately, this limitation still causes problems when passing the mock to a method with type-hinted arguments to the class rather than to an interface if we need to Dependency-inject the mock; or if we don’t have much choice because the the final class wasn’t implementing an interface. Library writers take heed if you define any of your classes as final; always write them with an interface that can be type-hinted.
So is there any way we can create a test double that matches type-hinting when we need to pass it into the class that we’re testing? I’ve been looking at an alternative approach to mocking that does allow me to create a test double that extends a final class.
I have heard people say that you shouldn’t test abstract classes or traits, only the concrete classes that implement or use them. I don’t follow that approach: unit testing is all about testing in isolation from anything that might affect those tests. Testing a concrete class that implements an abstract one, or uses a trait, means that the abstract class or trait is no longer fully isolated, but is being tested within the scope of the whole of that concrete class. We should still always test concrete classes as well; but we should also test the abstract classes and traits as individual units.
So just how do we test something that cannot be instantiated on its own?