Container Instantiation

Symptoms

A class is directly instantiating a PicoContainer and registering components within it.

Causes

This smell is most often found in unit tests. It could be as a result of Container Dependency. The container is supplied to the class being tested, which then uses it to locate its dependencies.

Another cause is using the container to build the object we are testing, which itself may have several dependencies. For example::

public void testCocktailWithVodkaIsAlcoholic() {
    DefaultPicoContainer container = new DefaultPicoContainer();
    container.registerComponentImplementation(Banana.class);
    container.registerComponentImplementation(Vanilla.class);
    container.registerComponentImplementation(Vodka.class);
    container.registerComponentImplementation(Cocktail.class);

    Cocktail cocktail = (Cocktail) container.getComponentInstance(Cocktail.class);

    assertTrue(cocktail.isAlcoholic());
}

What To Do

For unit tests like this, the class being tested should be instantiated directly by the test. Mock Objects should be used to "mock" the dependent objects, i.e. supplying a fake implementation that can have expectations set and verified on it, rather than a real implementataion. So, the test becomes:
public void testCocktailWithVodkaIsAlcoholic() {

    Banana banana = createMockBanana();
    Vanilla vanilla = createMockVanilla();
    Vodka vodka = createMockVodka();

    // set expectations on banana, vanilla and vodka here.

    Cocktail cocktail = new Cocktail(banana, vanilla, vodka);
    assertTrue(cocktail.isAlcoholic());

    // verify expectations on banana, vanilla and vodka here.
}

The implementation details of creating a mock object and setting and verifying expectations have been left out of the example, as the details depend on which mock object library/technique is used.

Exceptions

The container has to be instantiated somewhere!

Bootstrappers

A common place to instantiate containers is in some bootstrap class in the application.

Functional Tests

There may be a requirement to write a high-level "functional" test, in which you wish to test the interactions between a set of real components (not mocks). In this case, you may wish to create a container with the appropriate components registered for your test.

NanoContainer

If you are using NanoContainer, you can use NanoContainer's Standalone class (a bootstrapper) to start the application. All the container configuration can live in a script and NanoContainer (and thereby PicoContainer(s)) will be instantiated.