2008/9/12 Matthew Weier O'Phinney <[EMAIL PROTECTED]>:
> -- Giorgio Sironi <[EMAIL PROTECTED]> wrote
> (on Friday, 12 September 2008, 12:21 PM +0200):
>
>> I also have opened a topic in the fw-mvc list blaming the presence of
>> so many static classes in the framework components. Obviously you can
>> reset some of them, like Zend_Test_* does with the front controller
>> and the helper broker, but to me it feels like a workaround;
>
> This is something we also hope to address in 2.0. However, there are
> definitely some good reasons to have the front controller a singleton,
> and I haven't heard any truly compelling arguments for it not to be.
> Same goes for the helper broker. If you or others can suggest a design
> that meets the requirements of these components, I'm all ears, and
> welcome your input -- but just saying it's hackish and/or stinks doesn't
> really further the dialog.

Singletons are enemy of unit testing because they carry state around
the application. This state is bad because every test should be
independent of the others. That's the reason why the front controller
is reset in every setUp().
I think Zend_Controller_Front is currently a singleton because it has
to be globally accessible.
A rapid `grep -r "Zend_Controller_Front::getInstance" library/Zend/`
gives interesting results, for instance some helpers:
library/Zend/Controller/Action/Helper/Redirector.php
library/Zend/View/Helper/Url.php
This is a circular reference: how the helpers are supposed to be Unit
tested if they depends on the entire object graph of the application?
I think the request, response, router etc. objects can be injected by
a factory owned by the front controller (or passed in the dispatcher).
The helper broker is registered as the $_helper property of every
controller dispatched, so putting a HelperList object as a public
property of the front controller can help the dispatcher to produce a
new broker to put in the controller choosed.
The main flow of the application will be something like:
class Application
{
    $front = new Zend_Controller_Front();
    $front->helpers->add(...) //$front->getHelperList() if you want
    $front->getRequest()->add(array($_GET, $_POST, $_FILES, ...)); //
exagerating,
                                               // but superglobals are
also a global point of access
    $front->dispatch();
}
..
class AUnitTestCase
{
    $request = new Zend_Controller_Request(..);
    $helper = new Zend_Controller_Action_Helper_ActionStack($request, ...);
}
..
class AIntegrationTestCase
{
    $app = new Application();
    $app->getFront()->getRequest()->add(// .. whatever you want
    $app->dispatch('/');
    $this->assertQuery($app->getResponse(), ....);
}
(These are only examples of what I think can improve the unit
testability of components and applications).
More discussion forthcoming..

-- 
Giorgio Sironi
Piccolo Principe & Ossigeno Scripter
http://www.sourceforge.net/projects/ossigeno

Reply via email to