views:

388

answers:

2

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.)

+1  A: 

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.

Victor Farazdagi
I'm aware I can solve this with my own code, e.g. the way you described - what I'm asking is whether I have to do that or whether or not PHPUnit comes with flag internally. Though I suppose you could argue APPLICATION_ENV counts, even if that's, strictly speaking, external. [FYI, I'll upvote this once I can (at my daily cap at the moment).]
pinkgothic
I edited my question - hopefully it's clearer now :)
pinkgothic
+2  A: 

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!

Edward Z. Yang
Oh my goodness. I really am that dense. Thank you, that (= including the Bootstrap manually before the spl call) fixed it in both environments!
pinkgothic