It mainly depends on how you create your objects and how many classes access this APPMODE .
See what APPMODE does:
* DEBUG: All warnings and errors displayed, emails disabled and log messages * sent to console. Whether in-memory modifications to configuration * data are allowed
Something like this is usually solved by passing in "DebugLogger" and "DontSendEmailMailer" to the classes that should send mail.
To do this, you need only a few factories (or something else that you use to create a graph of objects) that you need to know about “production” and “development”.
The classes that make your actual business logic should not know if it works in production or not. This would mean that the developer of each class would have to take care of this, and each class would have to be modified if you ... say .. have an "intermediate" environment. It introduces a lot of global status, which, as you find, is difficult to verify.
If errors should be displayed or not resolved in the models of your php.ini or in the application boot buffer and should not concern the rest of your application.
I would start to move this "debugging" functionality from classes that require your APPMODE parameter, and move them to highlighted classes (logs, mailing lists, ...). The real thing (which actually sends mail) and the debugging thing (maybe it writes letters to disk?). Both of these classes can be tested correctly (testing a null logger is pretty simple;)), and you only need to do this switch a few times.
if($config->evironment() == "debug") { $logger = new DisplayEverythingLogger(); } else { $logger = new OnlyLogErrorsToTextfileLogger(); } $neededModel = new ClassThatDoesActualWork($logger); $controllerOrSomething = new ControllerOrWhatEveryDoesYourWorkflow($neededModel); $controllerOrSomething->dispatch();
etc. You can reduce the amount of global state step by step until you get rid of the definition and get only configuration settings.
When it comes to testing a class that works, you have now won the broadcast because registration has been implemented and you can go through the mock for testing.
So far for the first idea .. If you think this does not work, perhaps you can give an example of using APPMODE