Search code examples
phpzend-frameworkphpunitautoloadhtmlpurifier

PHPUnit and autoloaders: Determining whether code is running in test-scope?


Premise

I know that writing code to act differently when a test is run is hilariously bad practise, but I may've actually come across a scenario in which it may be necessary.

Specifically, I'm trying to test a very specific wrapper for HTML Purifier in the Zend framework - a View Helper, to be exact. The HTML Purifier autoloader is necessary because it uses a different logic to the autoloaders we otherwise have.

Problem

require()-ing the autoloader at the top of my View Helper class, gives me the following in test-scope:

HTML Purifier autoloader registrar is not compatible with non-static object methods due to PHP Bug #44144; Please do not use HTMLPurifier.autoload.php (or any file that includes this file); instead, place the code: spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload')) after your own autoloaders.

Replacing the require() with spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload')) as advertised means the test runs fine, but the View Helper dies a terrible death claiming:

Zend_Log[3707]: ErrorController caught LogicException "Passed array does not specify an existing static method (class 'HTMLPurifier_Bootstrap' not found)"

(Our test folder structure is slightly different to our Zend folder structure by necessity.)

Question(s)

After tinkering with it, I'm thinking I'll need to pick an autoloader-loading depending on whether things are in the test scope or not.

  1. Do I have another option to include HTMLPurifier's autoloading routine in both cases that I'm not seeing due to tunnel vision?

  2. If not, do I have to find a means to differentiate between test-environment and production-environment this with my own code (e.g. APPLICATION_ENV) - or does PHPUnit support this godawful hackery of mine natively by setting a constant that I could check whether its been defined(), or similar shenanigans? (My Google-fu here is weak! I'm probably just doing it wrong.)


Solution

  • HTML Purifier has its autoloading code placed in a file distinct from HTMLPurifier.auto.php; namely HTMLPurifier_Bootstrap. It has two methods: autoload, which actually performs an autoload, as well as getPath, which doesn't include a file put tells you where the file would be. This file is explicitly designed to stand alone.

    Unfortunately I'm not qualified to speak about Zend's code. You might be able to just get away with doing an extra include to Bootstrap before attempting the code. Hope that helps!