Testing traits with PHPUnit

How to properly test a PHP 5.4 trait with PHPUnit 3.7.


UPDATE (2012-09-22): Sadly GitHub Pages don’t allow to use Jekyll Plugins. Since Gists are embedded via the HTML <script> tag, the source code is not displayed in a client with JavaScript deactivated. Therefore I’ve updated my Liquid snippets, so that the following markup is generated after each HTML <script> tag:

<noscript><pre><code>Enable JavaScript to display the content.</code></pre></noscript>

That isn’t fully satisfying, but at least the user can now see that their exists more content that can’t be displayed in the client application.

Traits cannot be instantiated in PHP. Until this day, I always created a stub class to test a trait.

The source code in the following examples is taken from my PHP component HashCode. To begin with, the following source code represents my old solution (do not use that to test a trait):

  1. The stub class that is instantiated in the PHPUnit test class.
  2. The PHPUnit test class that instantiates the stub class.

With the release of PHPUnit 3.7 yesterday, I also came across this blogpost from the author of PHPUnit, Sebastian Bergmann. That post describes how-to test traits properly with the method getObjectForTrait. This doesn’t seem to be mentioned in the official PHPUnit manual, yet.

Following that instructions, the above code has been refactored to the following (proper) solution:

  • Replaced the instantiation of the stub class HashCodeTraitImpl with the method getObjectForTrait.
  • Replaced the method annotation @covers with the new annotation @coversDefaultClass from PHP_CodeCoverage 1.2.0. The class annotation @covers is used to define the fully-qualified class name once.
  • Created the Creation Method createObjectForTrait, to encapsulate the creation of an object for a trait.

And to finish this post, some offtopic information: I’m using gist-it.appspot.com from now on, to embed code from GitHub repositories into my webpages. gist-it.appspot.com turns any file of a GitHub repository into a “pseudo-Gist”, and makes it look similar to Gist.