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 thi开发者_如何学Cngs are in the test scope or not.
Do I have another option to include HTMLPurifier's autoloading routine in both cases that I'm not seeing due to tunnel vision?
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.)
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!
Well, although you are right about similarity (if not identity) requirement between production and test environments - I still have the configuration somewhat different. I mean bootstrapping loads different sections from application.ini, and as such I can simply pass the flag to turn sth on/off (like that autoloader feature):
1) I have SetEnv APPLICATION_ENV test in my .htaccess (could be production, development, staging). You can have it in your apache configs as well. 2) When Zend_Config loads application.ini - it loads it according to get_env('APPLICATION_ENV') - so different sections for different scenarios (I actually rely on Zend_Application of course, but it is clever enough to understand the environment) 3) I can always add some flag into respective section and check it from code.
Hope this helps a little.
精彩评论