Showing posts with label dependency injection. Show all posts
Showing posts with label dependency injection. Show all posts

Tuesday, February 23, 2010

The 50000 feet view and Dependency Injection

One criticism of Dependency Injection is the supposed unnecessary abstraction over collaborators that it is imposed by the constructor and setter injection techniques. Writing:
class Computer
{
    public function __construct(Cpu $cpu) {
        $this->_cpu = $cpu; 
    } 
}
instead of:
class Computer
{
    public function __construct() {
        $this->_cpu = new AmdCpu(); 
    } 
}
is said as being too abstract because a new programmer that starts reading the source code of the Computer class does not know what collaborator concrete class is used by Computer and does not know where to look for the code defining its behavior. In general, he just can't draw a picture of the overall object graph since the links between objects are scattered in many different classes and interfaces. A 50000 feet view of the system (a representation at the same level of detail of viewing a city from a plane) is difficult to grasp just from the method signatures of a highly decoupled system.
Fortunately Dependency Injection actually is about separating the construction of the object graph from the business logic, and the seams that define how classes work together are left abstract by design. Someone must construct the application or its components anyway, but the process is well encapsulated without the involved collaborators knowledge. The construction process is so decoupled from the system that it can take advantage of a DI container without introducing further coupling.
Thus in a well-written application there is already a nice 50000 feet view of the system, being it kept in a factory class or in the configuration of the DI container. A developer starting to work on a component should look at the code that constructs it in the first place.
For instance, the SpecificationLoader component of NakedPhp is a Facade composed of many different classes. The NakedPhp\Reflect\ReflectFactory class contains a createSpecificationLoader() method:
    /**
     * @return SpecificationLoader
     */
    public function createSpecificationLoader($folder, $prefix)
    {
        if (!isset($this->_specLoader)) {
            $this->_specLoader = new PhpSpecificationLoader(
                new PhpSpecificationFactory(
                    new FilesystemClassDiscoverer($folder, $prefix)
                ),
                new PhpIntrospectorFactory(
                    new FactoriesFacetProcessor(array(
                        new FacetFactory\PropertyMethodsFacetFactory,
                        new FacetFactory\ActionMethodsFacetFactory
                    )),
                    new ProgModelFactory(
                        new MethodsReflector(
                            new DocblockParser
                        )
                    )
                )
            );
        }
        return $this->_specLoader;
    }
}
This is a very practical 50000 feet view: it does not involve diagrams; it expresses dependencies between all the classes that constitute the component at the same time. Moreover, it is automatically kept synchronized with actual code refactoring since there is no external documentation involved (Code is the design). Dependency Injection is not snake oil: it's the best practice you can apply to object-oriented code.

Saturday, November 21, 2009

Mocking static methods: the road to Hell...

...is paved with good intentions.
On Thursday I came across the video presentation of a tool to mock static methods in Java:
PowerMock can be used to test code normally regarded as untestable! Have you ever heard anyone say that you should never use static or final methods in your code because it makes them impossible to test? Have you ever changed a method from private to protected for the sake of testability? What about avoiding “new”?
Horror. Not because of the technological revolution - maybe being able to subclass final classes only in the test suite would be fine, and this is just monkey patching - but because static methods have nothing to do with testability. Or, they make code untestable, but testing is not the reason why we want to avoid them.

Dependency Injection is not about testing: it is about good, decoupled design and reusable units. Static calls represent hidden connections between your classes that are not listed anywhere, and they give access to global and usually mutable state. They help creating a misleading Api and constitute the procedural part of object-oriented programming.
This is an example of bad Api:
<?php
class UserRepository
{
    public function getAllUsers()
    {
          return Db::findMany('User');
          // this would be the same: 
          // return Db::getInstance()->findMany('User'); 
    }
}
If in different tests we use this code:
$repository = new UserRepository();
$users = $repository->getAllUsers();
we probably get different results. But why? We had instantiated the same object and called the same method without any parameters. This Api is far from being referential transparent, and that's because it has a static reference that jumps to global state instead of having it injected.
So the question is not How can I mock a static method?, but How can I avoid static methods?
<?php
class UserRepository
{
    private $_db;

    public function __construct(Db $db)
    {
        $this->_db = $db; 
    }
    public function getAllUsers()
    {
          $this->_db->findMany('User');
    }
}
<sarcasm>It was very difficult, isn't it?</sarcasm> Dependency Injection is in fact very simple: ask for what you need, so that people that read your code know where collaborators are coming from and you are not secretly smuggling them in your classes.

I once heard a talk by Misko Hevery where he was making a point about dangerous global state, and he described the following situation. Suppose you have your beautiful test suite, and some classes in it accesses global state, so the tests are not real unit tests but have a bit of integration in their hearts. Keep in mind that in this environment tests are not isolated, since they depend on some global variables, maybe masked as singletons or static classes. The order of execution matters.
So you have MyClassTest, that is the last test case to run in the hour-long test suite, and it is failing. So you try to run it alone, and it pass. Then you run the suite again to figure out what is happening, and it fails again. The test is referencing some global state in which particular data is placed by the other tests before MyClassTest is run. The only way to hava a reliable failing is to run all the suite to set up the global state necessary.
The conclusion is: good luck in finding what is making MyClassTest failing.

Static methods are not object-oriented: they are a recipe for problems if they carry hidden state. They are global, because you cannot keep them on an instance you can throw away after tests. They make the Api difficult to grasp by hiding dependencies under the carpet. The solution is not "Let's open up the hood and wire these things differently so that we can mock static methods", but "Let's not use static methods."
You should even write the tests before the production code if you can. We do not write them only because they catch bugs and regression, but also because real unit tests force to code in a clean and decoupled design. If you are able to unit test your application, its architecture and flow is composed of focused, reliable and reusable parts. If you use static methods and spread new operators everywhere, there are hidden connections between components and mocking these things it's only Action at a distance.

Thursday, November 19, 2009

More questions on controllers testing

Sune wrote to me yesterday with some questions about testing Zend Framework controllers and proper dependency injection, which to me is a fundamental practice in object-oriented programming. I have already responded to similar mails in the past and this seems to be an hot topic nowadays, so as always I think other readers can benefit from this discussion and I'm sharing it here.
Because of you I am trying to move my software to use factories and dependency injection, also removing
singletons and Zend_Registry usage in controllers. But I am a bit confused, what is the right way to do this.
My plan is to bootstrap the main factory in the bootstrapper, and then use
$this->getInvokeArg('bootstrap')->getResource('factory') in controllers. Is this good practice?
Summarizing, the best thing would be creating the controller by yourself (or having its creation configured someway), but it can be an overkill to set up a similar approach on a Zend Framework application, since it requires a third-party DI container and controllers should always be thin.
Thin controllers means we probably want only to perform integration testing on them with Zend_Test, and not real unit testing as there is not much logic to exercise.
Since we cannot create in the bootstrap all the collaborators that could be possibly needed (we want to lazy-load collaborators that may not be referenced), your approach is similar to a Guice provider and I think it is very valid. In integration testing you should then use a different factory or configure this one to provide some fake components when the real ones are not applicable. For instance, a mailing service object ca be replaced with a fake implementation that records all the sent mail and lets you assert on them.
And in conjunction with that. Would it be good practice to inject a Zend_Config object into the factory?
Some models requires options from the config file, smtp username etc. and the factory would need those information to create the models.
Of course. It's up to you how to organize the config object, and you can and should change part of it in the testing environment. The power of DI containers is that during configuration you can specify not only scalars like database connection strings, but also different classes and implementation for the collaborators you inject.

Wednesday, November 18, 2009

To set or not to set

You probably know I am a test-infected developer and big proponent of Dependency Injection. You also have seen from the examples in this blog that I favor constructor injection, where a component asks for his collaborators in its own constructor:
class FacebookService
{
    private $_httpClient;
    public function __construct(HttpClient $client)
    {
        $this->_httpClient = $client;
    }
}
A factory or a configurable container can then recursively resolve dependencies and provide the class with what it asks for. The constructor's wiring code is dumb to write, but it is very concise and expresses intent: assigning the collaborator to a private property which will not be subsequently touched (as there are no setters).
The Api is also very clear as the constructor specifies everything is needed to compile and instantiate this class, while it does not provide the means to change the collaborators.

When the collaborators number is high, however, we may find difficult to use a constructor with a long signature. The obvious solution is trying to reduce coupling and analyzing the collaborators to see if everyone of them is really mandatory. It may be the case of a class that has too much responsibilities in accessing different parts of the object graph, or that collaborators leak into the class while they should be encapsulated in some other component.
Sometimes, there is nothing we can do to reduce the collaborators number:
class CommentsRepository
{
    private $_dbAdapter;
    private $_mailer;
    private $_logger;

    public function __construct(Zend_Db_Adapter $dbAdapter = null,
                                Zend_Mail_Transport_Abstract $mailer = null,
                                Logger $logger = null)
    {
        $this->_dbAdapter = $dbAdapter;
        $this->_mailer = $mailer;
        $this->_logger = $logger;
    }
}
This happens in some common cases:
  • the collaborators are options (value objects or scalars) which change the behavior of the component;
  • the class is a mediator between many objects and it is its own responsibility to deal with many collaborators.
Again, we can try to minimize the options or the objects involved, but the essential complexity will never vanish. Another solution might be passing the services via a method parameter only when they are used, but it usually violates encapsulation (a Controller having to keep a reference to a Logger even if it does not use it). Moreover, they may be needed in every method.
A long constructor is not clear as in almost any languages there are no named parameters (thanks Python) and we can forgot the parameters order in manual injection, or we may find difficult to extract automatically metadata on the collaborators if we are in a dynamic language like php.
The type of dependency injection we should adopt is slightly different: setter injection. This approach transforms the CommentsRepository class in:
class CommentsRepository
{
    private $_dbAdapter;
    private $_mailer;
    private $_logger;

    public function setDbAdapter(Zend_Db_Adapter $dbAdapter)
    {
        $this->_dbAdapter = $dbAdapter;
    }

    public function setMailer(Zend_Mail_Transport_Abstract $mailer)
    {
        $this->_mailer = $mailer;
    }

    public function setLogger(Logger $logger)
    {
        $this->_logger = $logger;
    }
}
Though, there are some problems with setter injection that we should solve:
  • setters allow changing collaborators after the construction: often it is a conterproductive operation and so it should be avoided. The setters can check if the corresponding private property is null before accepting the parameter.
  • the Api is not clear: why there are setters if I cannot set anything? I suggest to extract an interface where the setters are not present. This solves also the previous problem as the client class will depend only on an interface where setters are not defined and in static languages it is not even allowed to call them. In dynamic languages, the developer should refer to the Api documentation of CommentsRepositoryInterface and not of the CommentsRepository concrete class.
  • we may forgot a collaborator: both in manual and automated dependency injection you can forgot to call a setter or to add a collaborator to the configuration, and the result is a broken object hanging around. So you should maintain some form of test for the factory or the container (typically in integration tests). A missing collaborator is a wiring bug and it is simple to solve since it is going to manifest nearly always: the application will explode saying you called a method on null. Note that since I use null defaults for constructor parameters this problem is also present in constructor injection.
I hope you consider setter injection, as I avoided it without real reasons in the past and the design of your application can benefit from it.

Saturday, November 14, 2009

How to eliminate singletons (part 2)

In the previous post I hacked-up a very small component for automating dependency injection of php classes, which mimic the behavior of the moltitude of dependency injection frameworks out there.
The question arised in the last part of the article was How can I construct objects with a shorter lifetime than the application-wide one? In Zend Framework's case there are many controllers and view helpers that we want to instantiate only if necessary and which proper instantiation should happen only after a bit of logic has been executed, for instance after the http request has been elaborated by the router to produce a controller name.

With manual dependency injection the solution would be straightforward: just inject a ControllerFactory in the Zend_Controller_Dispatcher_Standard, which is the object that currently creates the controller. But the Zend_Controller component manages userland controllers and we cannot code a factory in advance to cover the possible use cases in every domain, nor we want the end-user to write boilerplate code in the form of a factory for his controllers.
Since the only viable solution is automatic dependency injection, we should create a configurable factory instead:
$controllersConfig = array(
    'My_Controller' => array(
        'myClass' => 'My_Class'
    ),
    'My_Class' => array(
        // ...My_Class's collaborator names listed by key
    )
);
$frameworkConfig = array(
    'Zend_Controller_Dispatcher_Standard' => array(
        'controllerProvider' => 'Zend_Controller_Provider' 
    ),
    'Zend_Controller_Provider' => array(
        'config' => new Zend_Config($controllerConfig) 
    )
    // ...collaborator configuration of the router, the front controller, etc.
);
I use the name Provider since it was popularized by Guice, but it is in fact a configurable Abstract Factory. The Zend_Controller_Provider class can be decoupled with a small interface:
interface  Zend_Controller_Provider_Interface
{
    public function getController($name);
}
class Zend_Controller_Provider extends Injector 
      implements Zend_Controller_Provider_Interface
{
    public function __construct($options)
    {
        parent::__construct($options['config']);
    } 
 
    public function getController($name) 
    {
        return $this->newInstance($name);
    }
}
The provider subclasses the Injector from the previous example to keep the code example short, but using composition of an Injector instance would make no difference.
The Injector code has to be extended a little to allow specifying objects in the configuration:
<?php
class Injector
{
    // ... constructor and private members
    public function newInstance($class)
    {
        if (is_object($class)) {
            return $class;
        }
        // default flow
        if (!isset($this->_config[$class])) {
            // it's a literal value like 'mydbpassword';
            return $class;
        }
        $collaborators = array();
        foreach ($this->_config[$class] as $collaboratorName => $collaboratorClass) {
            $collaborators[$collaboratorName] = $this->newInstance($collaboratorClass);
        }
        return new $class($collaborators);
    }
}
Including objects in the configuration should be done only in the case we need collaborators which are really only Value Objects with no behavior, like Zend_Config. It would be more complicated to set up different Zend_Config objects for injection, while it is actually a newable class (and so should not be injected, like we would not inject an ArrayObject).

Let's list the advantages we have just gained:
  • Independent instantiation of controllers. The Dispatcher will new only the controller actually needed (but it is the injector that will call new). Another provider can be set up for view helpers and other short-lived classes.
  • Real unit testing for controllers and view helpers: it will be easy to inject stubs and mocks in a controller since now it is forced to have setters or a unified constructor.
  • Real unit testing for the dispatcher: we can inject easily a fake Zend_Controller_Provider_Interface implementation, and test that given the right parameters it requests the chosen controller class.
Note that it is correct for shorter-lived classes to have field references to longer-lived ones. For instance the Url view helper should be injected with the current instance of the router since it needs the collaboration of something that knows all the defined routes. So one more question arises: how the problem can be solved now, given that the Zend_Controller_Provider class is created only with a Zend_Config as a parameter?
The simplest thing that can work in this case is to implement a generic Provider interface with a setInjector(Injector $longLiveInjector) method, so that when the interface is detected the original injector can create a clone of itself (that still references the created objects) and pass it to the short-lived objects provider, in this example Zend_Controller_Provider. The Provider then can add to its Injector the controller configuration instead of extending it, even favoring composition over inheritance.

I'm sure production-ready DI frameworks solve all these problems and maybe other ones, since it took us only two days to figure out the theory of operations. Automated Dependency Injection is a must-have in Zend Framework 2.0 and this is a proof of concept of how it can be implemented.

Friday, November 13, 2009

How to eliminate singletons

There has already been a bit of discussion in the zf-contributors mailing list and in the wiki about the Zend Framework 2.0 roadmap, which will guide the Zend Framework's evolution in php 5.3 and the new classes' development.
One of the key point in the architectural discussion is singletons usage. Singletons are scheduled for termination and in my opinion they just have to go (unless they represent a global state which cannot be reset for real, such as autoloading).

It is actually very simple to eliminate singletons: just force the components to ask for what they need in the constructor or via setters or via inject*() methods, instead of looking up a singleton trough a static method only to obtain a reference.
Once this fundamental decoupling is achieved, the hard part is tackling the construction problem: Zend Framework has a big codebase and writing a factory (manual dependency injection) for every use case is not viable.
Thus, automatic dependency injection needs to be called upon. There are many xml-configured dependency injection frameworks for php to incorporate, but let's show a simple example of how they works.

Suppose we want a reference to an instance of My_Class in a controller, and we want to have its collaborators automatically injected by some component. As the requirements say, My_Class has a unified constructor which would pass the collaborators to the setters, but dependencies resolution is possible also with setter-based injection. I would really prefer a bunch of setters if there are many dependencies.
This code is based on Zend Framework 1.x classes as I do not want to counfound anyone.
<?php
class My_Class
{
    public function __construct($options)
    {
        // calling setters or having them called...
    }

    public function setAdapter(Zend_Db_Adapter $adapter)
    {
        if (isset($this->_adapter)) {
            throw new Exception('Adapter cannot be changed once set.');
        }
        $this->_adapter = $adapter;
    }
}
Since I want to show how to eliminate singletons, I have declared a dependency towards a Zend_Db_Adapter instance, which is commonly put in Zend_Db_Table::setDefaultAdapter() as a singleton. It does not matter that singletonitis is cared for by another class: in this case it is still mutable global state and the same problem is present for the front controller instance. I did not feel like including a Zend_Front_Controller instance in this example as it is often used only as a mean to access other objects, and the underlying problem (Law of Demeter breakage) is not resolved by injecting it.

Configuration has to be defined in a plain old array which will be used by the container:
<?php
$config = array(
    'My_Class' => array(
        'adapter' => 'Zend_Db_Adapter_Mysqli'
    ),
    'Zend_Db_Adapter_Mysqli' => array(
        'driver_options' => ...  // username and password here
    ),
    'My_Controller' => array(
        'my_class' => 'My_Class'
    )
);
Eventually, the controller can now ask for collaborators instead of grabbing them from other sources. This data structure is very basic but it will do the trick for now.
An automatic dependency injection component would simply recursively resolve dependencies:
<?php
class Injector
{
    private $_config;

    public function __construct($config) { // assigning config to private member.. }

    public function newInstance($class)
    {
        if (!isset($this->_config[$class])) {
            // it's a literal value like 'mydbpassword';
            return $class;
        }
        $collaborators = array();
        foreach ($this->_config[$class] as $collaboratorName => $collaboratorClass) {
            $collaborators[$collaboratorName] = $this->newInstance($collaboratorClass);
        }
        return new $class($collaborators);
    }
}
and the bootstrap would be very simple:
$injector = new Injector($config);
$application = $injector->newInstance('Zend_Application');
Of course Zend_Application might be refactored to become the injector itself, so the object really constructed could be an action or a front controller. This code is very basic and can be improved with objects caching (to prevent multiple connections from being instantiated) where appropriate, a list of "global" classes (which scope is however limited to a Zend_Application object and can be throwed away whenever you want) to prevent configuration to grow too much, and in another hundred ways.

The problem with this approach is that we have, for example, to instance all the controllers and all the view helpers because we don't know which will be used during this request, since the object graph construction process is completed before the request management: what did you expect from ten lines of not-TDDed code? :)
This paradigm of one-time instantiation is typical in Java applications, where nearly eveything is instanced in the bootstrap "just in case". Php has a shared-nothing architecture and instancing more than the necessary objects would be a waste.
In the next post I will solve this big issue using deferred istantiation and different injectors, and showing how nearly all singletons can be reduced to injected collaborators.

Thursday, November 12, 2009

Zend Framework 2.0

I just wrote in a comment that Zend Framework 2.x did not yet exist and, today, the lead developer Matthew Weier O'Phinney has posted the roadmap for the 2.0 version of the framework, invitating php developers to participate in the discussion by commenting on the wiki or via the zf-contributors mailing list.
I already posted some questions on the wiki, but I would like to expand my thoughts on the architectural changes from a testing and design point of views, that are what interest my readers.
Here's a list of the guidelines that have the greatest impact.

Unified constructor
Every injectable class will have a constructor which accepts an array or a Zend_Config (I guess it will become Zend\Config) instance whose elements are passed to setters. This is becoming more and more the most adopted injection paradigm also in the 1.x branch. A standard is necessary and in a dynamic language like php the unified constructor works well, while accessing type hinting via reflection like Dependency Injection frameworks do in static-typed languages is troublesome and I don't even now if it is possible.

Elimination of singletons
Eventually, singletons will be refactored and we will stop seeing Zend_Controller_Front::getInstance() calls scattered in all the codebase. The various reset operations accomplished by the Zend_Test component during tests teardown should have hinted that something was fundamentally problematic in the design.

Design by contract
Multiple implementations of interfaces should be allowed by injection hooks, and interfaces should be extracted where needed. The abstract base classes so diffused in the 1.x version of the framework do not make easier to favor composition over inheritance since they force our classes to choose them as the unique parent.

Exceptions without inheritance
An example of avoiding problematic inheritance is the elimination of deep inheritance trees for exceptions. Base exceptions of a component should be interfaces. This is a finess I appreciate.

Namespaces
Obviously php 5.3 namespaces will be adopted and the _ in class names will be substituted by the \ namespace separator.
A thing I downvote is the separate namespace for testing: I would rather have unit tests in a parallel tree like they were in java packages (library/Zend/Filter/Int.php and tests/Zend/Filter/IntTest.php). A parallel structure gives different advantages:
  • saves the developer from having to import classes he is writing tests for;
  • naming collision with the production code are impossible since the class and file names in the parallel tree all end with 'Test.php';
  • the unique use statements expose only the imports the code is performing from different namespaces, expressing the real coupling of the system under test. Coupling to classes which live in the same folder is often inevitable and is not interesting to keep it under control.
Mvc implementation
The Mvc implementation (Zend_Controller) will undergo some surgery to improve performance and simplicity. In my opinion many features can be dropped: for instance I stopped using the action stack to perform multiple operations because it was too slow. It is also not test-friendly since you cannot assert that different actions were performed: I prefer to simply keep my logic out of controllers, so I see no use for great features in request dispatching as long as controllers are proposed as thin classes.
The point of the design by contract paradigm is to gain freedom in setting up the Mvc stack and injecting different collaborators which adhere to the contract. I saw the Phly_Mvc reference implementation and the interfaces are already present; it also uses a publish/subscribe pattern to dispatch events. In Zend Framework 1 we were able to substitute parts of the Mvc machine only by subclassing, while in 2 the approach will be cleaner as code will only depend on an interface.

Zend_Session
The backward-compatibility break in 2.0 version is the right time for changing also Zend_Session and improving its Api and behavior. Testing that involves sessions is difficult and I think the right approach is not transforming Zend_Session in a singleton, but decoupling the controllers code with a session container, which implementation can be injected during bootstrap: it is something I would want to isolate just like a mail service.
The Zend_Session_Namespace objects in 1.x access directly the $_SESSION variable, mutating global state and becoming hard to test: a different solution could be placing them in a $_SESSION variable when they are constructed or reconstituted in their factory (which now does not exist). Anyway, the session namespace objects should do less work, particularly in the constructor.

The discussion is important as we are now shaping the future framework. Feel free to counterargue in the comments and in the wiki. :)

Saturday, November 07, 2009

Questions on controllers testing

A different kind of controllerDavid Weinraub has written to me asking some basic questions about my last post on dropping unit testing for controllers. I am glad to write a less technically advanced post to answer these questions for the readers that experience difficult in following the discussion in the previous post. I guess it can be helpful for other developers that have just started exploring the possibilities of good object-oriented programming.
Let's start with the questions.
On your recent post How to not test controllers, you have the following code in a controller:
$repository = $this->application->factory->getUserRepository();
Was this what you meant in our previous discussion by using a single app-wide factory for creating your service objects? The factory with approx 100 calls to "new"?
In my opinion pure factories should have nearly no logic: they only create objects and their responsibility resides here. Though, in my approach only the controllers know that a factory exists.
So you create this $factory at some early phase, bootstrap I guess, and then "store" it as an attribute on the $application object? Presumably the $application object is always accessible wherever I am in the app, so if I need some service, either to use directly or to pass as a collaborator to some other service (like a repository or a mailer), I can get it using code like the above.
The container which provides the factory is not important, but in this case is the Zend Framework bootstrap object or a Zend_Application instance, the only things that the infrastructure allows us to inject into controllers. It would be great, alternatively, to inject only necessary services in the controller, having also the controller object created by the factory (but it's not supported out of the box in zd).
Note that for easiness of decoupling and testing, this choice is bad: every time we break the Law of Demeter in a class its tests will increase in size and complexity. Normally I want to avoid these violations but since I decided to treat the controllers only as wiring code and not to unit test them it's not a problem. All my business logic is kept in the underlying domain layer if it is domain related or in action and view helpers if it is focused on data formats like html and json, or other cross-cutting concerns; these classes are then extensively tested and writed via TDD. I test controllers only in integration, and their responsibility is to act as a dumb bridge between requests/view variables and the Domain Model. Controllers are only very simple mediators in my applications: I would unit test them if I do not have to import third-party libraries to inject their collaborators, because their Api will improve.
Perhaps the factory itself calls it's own methods when it needs to create more complicated services using collaborator services?
I do this all the time. It's stupid to not reuse code :) However, it is usually simpler to expose only the narrow set of end-user services: for instance my Reflector, which gathers domain classes metadata, is used only by other services and so it is created in a protected method. Only the services which are requested directly by controllers earn a public method.
Does this factory maintain an internal registry of the objects it has created, so that subsequent calls to the factory do not produce duplicates of the objects? Or alternatively, is it is "dumb" factory, so that each call to, say, getUserRepository() creates a new one. I can't imagine you allow your factory to make duplicates like that.
If you want, you can cache them in the factory field references, and even unit test the factory by requesting the same service twice and executing assertSame() on the objects returned. In php it's not very useful: how many times a service is requested two times from the factory, by the same controller? It makes a lot of sense in Java where objects are not garbage-collected between http requests and can thus be shared. It is also necessary in php mainly when a collaborator must be shared between different services.
The nice caveat is that if you implement consistently this caching also the smaller factories (which create objects with shorter lifetimes like View Helpers) will be cached as they are instanced once in the main factory and then shared. This is true with every level of nested factories you reach and, without using singletons, you will never need to duplicate an object when not needed.

I guess I have clarifyied why I am abandoning unit testing for controllers and making them break the Law of Demeter, without feeling remorse or renouncing to a good design. Feel free to post comments to continue the discussion.
The image at the top is a photograph of a SNES controller. This is a pun and not the controller we are talking about.

Friday, November 06, 2009

How to not test controllers

Yesterday on twitter a discussion started about how to properly design Zend Framework action controllers to allow simplicity of testing, specifically how to inject collaborators in controllers and to avoid breaking the law of Demeter.
The example problem is how to get a reference to a MailService instance for executing this code inside a controller:
$user->sendWelcomeEmail($mailService);
where $user is an istance of the User entity class, thus having no injected services and requiring one to be passed as an argument to the function. This problem was proposed by @apinstein.
I can think of several solutions, and others have been proposed by @beberlei and @weierophinney.

1. Just inject the MailService in the controller: it should ask for the collaborator in the constructor (@mhevery)
This would be correct in Java and it is an example of pure design, but in Zend Framework constructor injection is not available for controllers. They are required to have a no-arguments constructor: this contract leads us to the next solution.

2. Controllers may not have constructors, but there are still ways to inject services/models (@weierophinney).
3. Yadif allows to inject #zf controllers.(@beberlei)
Yadif is a dependency injection framework for php that implements setter injection. Using Yadif in conjunction with setters prepared on the controllers let you unit test them as you can call the setters in test code to pass in stubs and fake objects.

4. Instance the collaborators as bootstrap resources and leave them hanging there waiting for the controllers to use them.
The bootstrap object acts as a service locator. If I understand this process, and we want to unit test the controllers, we should avoid a service locator as it involves breaking the Law of Demeter (getting the bootstrap object only to get the collaborators), and we would have to prepare the container only to put in services, without the Api of the controller telling us what collaborators a controller depends upon.
Also instancing services that might not be used during every request can be expensive. I don't know if there is a lazy loading capability for bootstrap resources. This option is the worst for testing and maintenance.

5. Push down the logic in the model layer (me)
Controllers in Zend Framework are meant as a thin layer over a large domain model one. There is no problem for me in not having easy injection in them because I would put in the controllers only wiring code, which receives the main factory from the bootstrap, request it to create the domain services which have to do the real work and pass request parameters to them, assigning view variables as a side-effect.
$repository = $this->application->factory->getUserRepository();
$user = new User(...); // with a factory if you prefer
$view->message = $repository->registerUser($user);
I know this is breaking the Law of Demeter, but the point here is that if the controller is a thin enough layer, which contains no logic, there is no need to unit test it, and experience the pain of preparing stubs that return stubs that return stubs. This code will be exercised in integration tests that have all the same bootstrap, stubbing the main factory to provide fake collaborators only where they are not practical (a fake MailService in this case).
Here are the reason why I like this approach to controllers:
  • reusability: controllers code is not reusable, to the point that it is suggested to move much of it in helper classes. I do not want to rewrite logic in different places, so it's better for me to keep business logic in the domain layer.
  • simplification: if the controllers are dumb and expose the underlying layers as-is, that would be no translation between the domain model and the end user mental model. The entities presented in the user interface will be the same that live in the domain layer.
  • testing: mocking an array of domain parameters is simpler than mocking request objects. Obviously unit testing is performed only in the domain layer.
  • abstraction: logic is not technology dependent. If you keep logic in the controllers, you are coupled to Zend Framework, while a domain model is agnostic on every other component of the application, isolated by interfaces. It's like using a DataMapper instead of an ActiveRecord.
I avoid so much smart controllers that I recently started to implement the Naked objects pattern, where controllers are generated and delegate all the work to the domain model.

In conclusion, I think you should consider all these five practices for improving your controllers design and make sure your business logic is well tested. Choose the solution that works for you.

Wednesday, November 04, 2009

Testing and constructors

During unit tests preparation you often have to modify your design to simplify the test code. Design for testability is one of the good things about Test-Driven Development and more in generally of unit testing (and with TDD you will not modify your code to allow easier testing but you will write it to do so). A testable design is decoupled and maintainable and in the long run you will get only advantages. With in the long run I intend next week.
One of the pillars of design for testability, which is listed also in the Google guide for code reviewers, is to have constructors that do not contain logic or method calls. I will explain the reasons behind this choice with an example, but let me say that to reduce dependencies it is natural for a class to avoid making assumptions on the external environment, performing things like creating new objects. Separating the business responsibility of a class from the one of wiring itself to other objects is necessary.

As always, the example is in php as there is a great need for good object-oriented programming in this particular field.
class NakedEntity
{
    protected $_entity;
    protected $_class;

    public function __construct($entity = null, NakedEntityClass $class = null)
    {
        $this->_entity = $entity;
        $this->_class = $class;
    }

    public function getState()
    {
        $state = array();
        foreach ($this->_class->getFields() as $name => $field) {
            $getter = 'get' . ucfirst($name);
            $state[$name] = $this->_wrapped->$getter();
        }
        return $state;
    }

    public function getMethods()
    {
        return $this->_class->getMethods();
    }

    // other methods...
}
I omitted docblocks as they are not relevant in this context.
This class purpose is to act as a container for a domain object and its class metadata. These metadata are kept in its $_class field which is a NakedClass object. The extraction process uses reflection and it is encapsulated in another component that returns instances of NakedClass and NakedEntity. Thus, creating a test-friendly NakedEntity object is simple:
$entity = new NakedEntity(new stdClass, new NakedClass('My_User', $methods));
This code snippet tricks my library classes in believing that a stdClass is a My_User istance, and makes unit tests very simple. For instance the classes that work on the methods metadata can try many different combinations of methods without requiring me to write many My_User and My_Group classes. I should thank my constructor: it does not perform work, but only accepts the collaborators and stores them in private fields. If the constructor of NakedEntity parsed the class code like this:
$user = new My_User();
$entity = new NakedEntity($user); // calling get_class() and then doing a lot of work
I would be stuck with My_User methods and I would have to write a new real class for every different test method and my tests would be slower.

Fortunately there is mocking, and I can substitute NakedEntity instances with mocks. But mocking won't always save me from the work in the constructor, as when testing the very NakedEntity class I will have to wait for all the parsing to finish in every test, while I just want to verify that, given a set of method metadata getMethod() and hasMethod() works well. Why should my classes parse docblocks and annotations to test ten lines of array-related code?
Unit testing also means that the code under test is contained in the NakedEntity class, and I can inject mocks or stubs via the constructor instead of a real entity or a real NakedEntityClass object. Keep in mind also that a stub can be the the real production class if a test-friendly instance can be built and it has not much logic: in other tests I often use the NakedEntity class, and I will continue at least until it grows to contain logic I want to take out of my other unit tests.
Focusing on the NakedEntityTest class instead, if the constructor created objects or did a lot of logic it would be difficult to inject the right stubs as they can get in the way during the costrunctor execution. Also a problem in the constructor would make all the tests fail, making more difficult to locate the problem.
One acceptable practice is to instance only newable objects in the constructor, with little behavior. In php an array is the obvious example of newable, since it is not even an object. Also I considered Spl classes newable as they do not slow down tests and cannot commonly break (at least you cannot break them while maintaining your code).

Note the null defaults that the arguments assume, that allow tests to pass in nulls instead of real objects or mocks. I think this is useful when sometimes a collaborator is not used in mediator objects:
$entity = new NakedEntity(null, $class); // emphasis that the test would
// use the NakedClass collaborator.
$methods = $entity->getMethods();
The contract in the code above says "getMethods() should not assume anything about the $this->_entity property". If getMethods() tries to call a method on a null, the code will explode and the test will fail.
It is responsibility of the factory class to create a valid object by passing in meaningful collaborators instead of nulls, and this responsibility would be exercised in an integration or functional test.

In my opinion this is the perfect constructor for my class:
  • it lets the tests inject collaborators, which could be real instances, mocks or stubs;
  • it does not perform work that should be repeated in every test; it only assigns variables to private or protected fields;
  • it lets the collaborators be null values if they should not be touched during a particular scenario.
I know someone will complain: but now how I can write new NakedEntity(...) to work with an instance? I will have to create all its collaborators. You should not do it. A factory should do it for you, and if you require to do it in the middle of a method, you should ask for a factory in the related constructor.
Do you have some example of constructor difficult to refactor in this way? Feel free to post it on pastebin.com and insert the link in the comments for discussing it.

Saturday, October 31, 2009

Object-oriented roundup: Halloween edition

This blog has grown much during the last month and the newest readers may have missed some important articles in the posts archive, on one of the most interesting topics here: object-oriented programming. Specifically, these posts reflect my vision and are meant to discuss good and practical design of classes.
This page will stay here as a way to quickly find references to the key blog posts of the past for me and the readers, while working on new articles.

First, I made a roundup of the most crucial and popular oop posts. I guess you have already read The Repository pattern and Object-oriented terminology if you are here.
  • Domain model is everything discusses the differences between the domain and infrastructure layers and how to get the best from both. Typically an infrastructure layer is reusable and is provided to the programmer as a library or framework, while the domain layer is the core of an application and is commonly written from scratch.
  • Never write the same code twice: Dependency Injection is an introduction to DI techniques, which allow to produce reusable and testable code. For any non-trivial project at least considering Dependency Injection is fundamental.
  • When to inject: the distinction between newables and injectables expands on the previous article about DI and makes distinctions about which classes are really suitable for injection of collaborators and the cases when it is an overkill.
  • Factory for everything focuses on the object graph building aspect of injection and on how to implement the [Abstract] Factory pattern, presenting a refactoring example towards it.
  • Object-oriented myths deals with common legends about supposed futility of good object-oriented design, such as overuse of factories and getters&setters versus encapsulation.
  • The rest of the object-oriented myths is the second part of the previous article on myths, and talks about singletons, lazy loading and Utility classes.
Then, I listed the articles in the SOLID principle series, which comprehends posts about the five object-oriented design principles officially formulated by Robert Martin (though they are not the work of a single man). This set of principles strives for loose coupling and reusability of components like classes and interfaces.
I hope you find these resources useful. Anyway, happy Halloween!

Tuesday, October 13, 2009

The rest of the object-oriented myths

This is the second part of the post Object-oriented myths. You may want to read the first part before going forward.

In the last post we were talking about the advantages of encapsulation, Dependency Injection and factories. Let's dig in other legends about object-oriented programming and how it makes you write boring and difficult to understand code (clue: it is not true).

''But I will need a Factory for every object. What a pain to write all these classes.''
No, this is not true, you will often need at most two or three factories. I have seen Misko Hevery answers this question multiple times in his blog and talks.
First, simple classes like entities, without collaborators, do not need factories. Second, the same factory which builds the application (at every http request if you are using a shared-nothing architecture such as php's one), builds everything with a lifetime equal to the request one. All these objects such as front controllers, loaders and so on are built from the same factory and injected as collaborators when you call MainFactory::createApplication().
Maybe you need other objects with a shorter lifetime: for instance consider view helpers for web applications, which are used for creating html code that would be boring to write by hand. Their creation can be encapsulated in a ViewHelperFactory class since it's a waste to create 50 helpers at every request when only a handful of them may be used. So an instance of ViewHelperFactory is built in MainFactory and then injected into the view object that renders the page. Helpers are thus created as needed.
This identical multiple-lifetime pattern is reflected in Java when dealing with Session-wide objects and Request-wide objects, the formers being built at the startup and the latters with a RequestFactory. You can have how many levels you want, for instance a MainFactory/SessionFactory (the principal one of the application) can create a RequestFactory which can in turn create a ViewHelperFactory, all these creations at different moments in execution. In php, though, everything is garbage collected at the end of the request so there's one less level.

''I should use a Singleton and implementing in it lazy loading, so that I make sure there is only one instance of my database connection, and only if it's used.''
What is the responsibility of your PDO/Zend_Db/My_Db_Adapter/Connection instance? Bridging your code with the database. It probably needs a QueryFactory if you create query objects by calling it, but it's not the point of this paragraph. So the responsibility of the db object is not to control that there is only one instance of it and nor it is to lazy load itself. This responsibility should be in its factory, which will cache the instance to perform lazy loading and ensure only one connection is created. Following the previous example, MainFactory will pass the same instance of DbFactory to all your classes that needs it, and the connection will be shared and conserved as a DbFactory private field. Consider also to just pass in the db object if you do not really need lazy connecting capabilities.
If you do not multiply the instances of a Factory, it can perform lazy loading and Singleton-like behavior, without obscuring your design with global state. And you can easily avoid duplication of factories by creating and kepting them in the MainFactory of your application. Using a Singleton is a symptom of unresolved dependency, since a Client class, with empty constructor and no setters, can reference a singleton, lying about what it needs to work correctly and causing debugging nightmares when an hidden collaborator breaks. You'll find out while testing, reusing and reading this type of code that it causes great pain: it's not an oop fault, but thoughtlessness of who designed the Singleton.

''Let's make an Utility static class where we can put all these methods. They seem to not have a place to live in.''
Using an Utility class is a smell that you have code which should belong to already existent classes. You should consider to put these methods in the objects which they work with, or to create services to give this code a home if they do not fit in an already existent class. In these service classes you can put cohesive sets of methods which depends on the same collaborators, instead of creating a big static Utility class where you sink all code that does not make sense elsewhere, and which becomes a concentrate of dependencies, being impossible to mock out. A service is passed only in the classes that need it instead.

I hope I have contaminated you with real, confident object-oriented programming ideas. Oop has a learning curve but it should not be difficult in the long run: it is a tool created to simplify the programmer's life and not to make him experience pain and boredom.

This post's title is an homage to The Rest of the Robots. Asimov is one of the few science fiction authors that keep me nailed to a book.

Monday, October 12, 2009

Object-oriented myths

I think object-oriented programming techniques should be explained with a context and not shouted out loud as philosophical principles. Sometimes these techniques are misinterpreted, or exaggerated and used as a weapon against oop proponents.
Some popular myths about oop have risen in the programming world, particularly in the php continent where object orientation is still in its infancy. I want to debunk these legends to show that good oop is actually easier than you think. For instance, Dependency Injection is one of the best thing that can happen to your code.


"You should not expose public fields. Write getters and setters instead."
The point of encapsulation is to protect client classes from changes in the collaborators. In what is using a set*() method different from a public field, for the cause of encapsulation?
There are some classes which only responsibility is to maintain state. We encounter them in every project, being their names User, Post, CreditCard, String, Regex and so on. It is correct for this type of classes to have getters and setters to change their internal state and fulfill their requirements.
The other type of classes are services: stateless objects which do complex work, are not serializable and may have internal and external dependencies, towards other services or processes. These classes should not have any get*() or set*() method, since they are by definition stateless and the list of getters will break encapsulation. If I were a client class I would require a BookRepository object to search books, because I use it to... search books and not to change the underlying database calling BookRepository::setDb(Zend_Db $db). It's not my job to pass the collaborators in: I use the object only to search books.
If you find a complex service class which also has a state, the most useful thing to do is to break up the class in little ones because the responsibility is too high for a single unit. Testability and cohesion will improve.
So without setters, how I get collaborators references in, for example, a ServiceClass object private fields? You can create them directly in ServiceClass methods (bad) or realize Dependency Injection, passing them in the constructor of ServiceClass. A Factory will then call new, passing in the collaborators and encapsulating the creation. This practice leads us to the next myth.

"Why using a factory? There's no point in creating an object only to create another one."
The process of an object's creation can be intensive and complicated. If you use Dependency Injection (and you probably should as it is a standard practice for producing solid object-oriented code), every object needs its collaborators passed in the constructor, and the collaborators need other collaborators and so on. It's useful to abstract away this process in a Factory class whose methods perform the construction in one centralized place. Again, entity objects like Strings, Users and Posts are a bit special and using a Factory for them is not required, provided that they don't even had collaborators.
Though, if you find yourself creating a factory and subsequently, in the next line of code, using its methods to create a business object, chances are the design can be improved. The principle is that objects should ask for things, and not look for them.
Let's make the following assumptions:
  • You write object-oriented applications, so all your code is kept in classes. This is not necessarily true for hybrid languages like php.
  • You strive for minimizing the coupling of your components, respecting the Law of Demeter. You want to reuse classes and you want to be able to test them in isolation.
So start with examining where you are creating a BusinessObject in a class Client. The possible cases are three (actually two):
  • (not possible) BusinessObject has a longer lifecycle than Client, so you cannot create it in Client. Ask for it in the constructor.
  • BusinessObject has the same lifecycle of Client: it's a collaborator. So stop using a factory and simply ask for BusinessObject in the constructor of Client.
  • BusinessObject has a shorter lifecycle than Client: it must be created at a specific time, when some method on Client is called.
The latter case is the most interesting one. If BusinessObject is an entity, you can create it directly: there are no external dependencies to inject and there is little behavior to mock out in tests. If BusinessObject is a service class, with one or more external dependencies and more than a bit of behavior, you should indeed use a Factory to encapsulate its creation. But since you strive to reduce coupling, Client must not know if BusinessObject calls methods on an hundred different objects or returns prepackaged results. So you should pass in a Factory object in the constructor of Client: this solution resembles an Abstract Factory pattern, with the difference that we are focusing on lifetimes and not on extensibility and introduction of new subtypes.
In sum, all direct service object creation (use of the new operator) should be encapsulated in Factories, which can be used in the application bootstrap or passed in the constructor of the Client class if you need object creation as a business requirement (and the object is more complex than a String). Obviously if you are using setter injection it does not make a great difference, but the Api will be more cluttered. If your setters does not accept multiple calls to change collaborators, they have my blessings.
Warning: all the class names used are examples. For instance Client and BusinessObject are two classes that could also be called A and B. I often use Client to denote a class which is attempting to create an object, according to the GoF terminology. BusinessObject is a generic name for a class, more readable than Foo and Bar.

This post is becoming too long to not lose focus, so I'll continue tomorrow with the rest of object-oriented myths.
You may want to subscribe to the feed to discover the other myths as soon as they are published.

Sunday, October 11, 2009

The value of abstractions

There is a constant trade-off between levels of abstraction and performance problems in software development and in other fields. We write code in high-level languages and not in assembly or machine code, but sometimes go down a level to write fast C extensions.
Every time you call a function, being it your own work or provided by a language or a framework, you are using an abstraction: is it worthwhile or you're wasting time writing bloated levels of indirection?

To understand the importance of abstractions in modern software, consider the process of retrieving a web page. When you type an url in the location bar of your browser, the following abstractions are taken advantage of:
  • first of all, the location bar, plus the form and inputs system, is an abstraction over the raw Hyper Text Transfer Protocol (HTTP). You don't write http requests by hand like GET /.
  • the http request and response are transported over a text flux based protocol which resides at a lower level of abstraction, the Transmission Control Protocol (TCP). The purpose of this abstraction is to free the high-level protocols from the burden of considering segmentation of messages.
  • the TCP layer then uses the underlying one, the Internet Protocol (IP), to deliver packets back and forth from your machine and the webserver, and to ensure their reliable transmission. IP abstracts away physical details by mapping internet hosts with numeric addresses, the famous ip addresses everyone is always talking about.
  • IP layer uses one or more data link layer protocols, such as Ethernet, to send frames of data between physical network points. These points are identified with Mac addresses in an Ethernet architecture.
  • While Ethernet is capable of physically transport data by changing the voltage over wires, it uses electronic circuits as black boxes that perform mathematical and logic calculations, like Cmos logic gates. These circuits present only binary voltage levels as their output and hide all the transistors they are constructed with.
That's a total of five levels of abstraction only to retrieve a web page. But there's more: every time you write a function or a class you are producing an abstraction. You hide the details of implementation as private members of a class and present a public Api which constitutes the abstraction considered. Moreover, if you design an object model, or a relational model, or every kind of model, you're abstracting away details from the real world. When writing the classic User class for a blogging application, you probably do not include the height or the eyes color of the user as a field.
Even assembler has procedures: multiple level of abstractions are present in every piece of software we encounter.

We have said that there is a trade-off in using abstractions: there are a lot of advantages in dealing with less data and a simplified model of the reality, built according to the desire of the abstraction user. This user can be an upper layer of abstraction or a real person. These advantages, however, come with a cost:
  • Performance cost. Every software layer has an overhead, which is time spent performing management operations and not business (read useful for the job at hand) ones. If you're calling an external method or function, you're pushing variables on the stack and passing the control to a subroutine: the cpu also must take the time to do allocate all local variables. More abstracted code is also prone to have a long execution complexity to consider every possible case it should manage. Multiplying these time costs for thousands of calls gives you the picture.
  • Limitations of the interface. When you want to do something the abstraction does not provide as a feature, you have to go down at a lower level and it's often a not pleasant activity.
  • Leaks. Sometimes an abstraction performs horribly if you do not take into consideration at all what it hides from your view. For instance, in Java the Remote Method Invocation feature lets you call methods on other phisycal machines objects, treating them as local instances. Imagine what happens when the connection is slow or too many calls are made...
The pros of abstraction, however, are usually by far more powerful than the cons:
  • Simplicity of the interface when there is no need to consider the underlying layer; think about the location bar of your browser again. This is a fundamental principle of software development, Divide et impera.
  • Standardization and reusing: the Tcp layer abstraction is used by all the upper level protocols, such as Ftp, Smtp, etc.; they do not have to implement their own low-level procedures.
  • Decoupling: the protocols from the upper layers and the high-level software components (if correctly designed with Dependency Injection) are decoupled from the low-level implementations. This is true for Ip which decouples browsers from knowing the voltage levels to transmit, and for Zend_Auth php objects which do not know if they are authenticating credentials against Ldap, a database table, or whatever.
The trade-off is present in nearly every component of a software application: a discussion started on my previous post on php profiling about whether it's right to use a framework and an Orm as abstractions on the php core capabilities, or to cut out the middle man and just access native php directly. In general, I am a fan of the abstraction choice, since the advantages it provides are concrete and immediate, while the disadvantages are only hypothetical. Maybe the performance will need optimization and caching; maybe the abstraction will leak details; but surely the developers work will be simpler than just using native php and the flexibility of the procuced code will be increased.
There is also the fear of overengineering an application. But don't let fear take control of your development process: do informed choices about using frameworks and external tools. Experiment and understand strong and weak points of different approaches before adopting or removing a level of abstraction.

One famous quote summarizes this post:
There is no problem in computer science which cannot be solved by one more level of indirection, except too many levels of indirection.

Thursday, October 08, 2009

Unit testing view helpers

The architecture of the Zend Framework, one of the most popular php frameworks, is very extensible and presents a lot of hooks for subclassing and new implementations. The problem which arises from time to time is the testability of the components produced: view helpers are an example of problematic testing and here I will write about solutions for unit testing them.

View helpers are a key point of the Mvc implementation in Zend Framework, along with the Zend_Controller component. The responsibility of view helpers is to keep programming logic out of the view scripts, which are rendered by the view object. We are talking about the presentational layer: every big of logic kept in a view helper can be reused in other scripts.
View helpers are instantiated on the fly by the view object (a Zend_View instance, or another Zend_View_Interface implementation) and kept there. This object will then include the scripts in a method, providing access to its scope to call fake methods with the name of view helpers (a __call() implementation). Since the scope of the object provides the $this handler, view scripts reference it to call view helpers:
<?php
echo $this->doctype();
?>
<html>
...
This script takes advantage of the Doctype view helper (a Zend_View_Helper_Doctype instance) to produce an html doctype declaration.
You can also write your own view helpers: according to the manual, they should provide an empty constructor to allow instantiation by the view object and a method which name corresponds to the class base name. For instance doctype() is the strategy method of Zend_View_Helper_Doctype.
The view helper class should implement Zend_View_Helper_Interface, which has the only injection point in this architecture, the setView() method.

The empty constructor is the problem in view helper management, since it gets in the way of simple test code when you write view helpers that make use of other view helpers as collaborators. For instance, I wrote yesterday a IconLoader helper which use the standard HeadStyle one to add css rules to the page.
The injection point which I was talking about, the setView() method, is called after instantiation. Once my IconLoader helper is instantiated, the view object injects itself in the helper using this method, providing a reference to other helpers.
In this design, the view acts as a Service Locator, and we have no idea which helpers could be called by another one: every helper class could depend on everything else.
Unit testing prescribes to test the helper class in isolation, substituting the collaborators with mocks or stubs. We have to put in test doubles as collaborators, otherwise we are testing more than one helper at the time and if the test fails we cannot tell if the problem is in the SUT (IconLoader) or in the referenced helpers (HeadStyle, ...). Note that collaborators can reference more collaborators, and soon IconLoader class can depend on the entire framework.

My very-simple-testing solution would be require helpers to specify their collaborators in the constructor or via setters, implementing Dependency Injection. We cannot change the standard Zend Framework architecture, though, but it's not a framework's fault. This solution would have required to build a small automatic dependency injection system, which is not in the scope of Zend Framework 1.x (but will be in 2.x as far as I know).

With the current architecture, we can make different choices to simplify testing (remember an helper's constructor must not have parameters, and we must test our components in isolation):
  • Use the real view object and the real view helpers as collaborators. This is integration testing, and failures on the collaborators or view object or what else they refer to will make my main test fail too. Moreover, at every test you should bootstrap all the Zend Framework's Mvc system, so it's not a viable solution.
  • Providing setters for collaborators. The view object cannot call these setters for us, so in the bootstrap we should require the view helper from the already set up view object and call the setters with the mandatory collaborators. In my example, I would have created a My_Helper_IconLoader::setHeadStyle() method. This is the simplest solution for testability, since we have only to call setters in the test for IconLoader view helper and passing in mocks; however, it requires to instantiate all view helpers which need collaborators at every page request, so it's a bit heavy but mandatory if the collaborators are not view helpers but other complex service classes. Starting to mock collaborators is right, though.
  • Mocking the view object/Service Locator with phpunit. This can be done for one view helper, by setting an expectation on a (mocked too) view object __call() method. But when using multiple helpers as collaborator, phpunit cannot distinguish between calls with different parameters and decide which collaborator helper to return. It's an hack which would not work very well.
  • Provide a Fake view object. This is my choice: write once a fake view class, which implements Zend_View_Interface but instead of creating view helpers only returns the ones set at construction time. The definition of a fake object is a class with a running implementation, but different from the production one, often a simplified implementation used for testing.
With my fake view object, the testing phase becomes very simple. In my setUp() method I have:
    $this->_headStyleMock = $this->getMock('Zend_View_Helper_HeadStyle', array('appendStyle'));
    $view = new View();
    $view->setHelper('headStyle', $this->_headStyleMock);
    $this->_helper = new IconLoader();
    $this->_helper->setView($view);
and after this injection, I can set expectations on $this->_headStyleMock and exercise IconLoader in the test methods.
You can find the View fake class at:
http://nakedphp.svn.sourceforge.net/viewvc/nakedphp/trunk/tests/NakedPhp/Stubs/View.php?revision=52&view=markup
along with some tests on it, which could help you grasp its usage:
http://nakedphp.svn.sourceforge.net/viewvc/nakedphp/trunk/tests/NakedPhp/Stubs/ViewTest.php?revision=52&view=markup
Obviously this fake class was Test-Driven Developed.



Feel free to ask any questions. I care about (unit) testability and using extensively frameworks can often make difficult the TDDer life.

Featured post

A map metaphor for architectural diagrams

It is a (two-dimension) representation of a pipe. The map is not the territory , but in software engineering terms they are models of it....

Popular posts