Tech and Media Labs
This site uses cookies to improve the user experience.




Unit Testing

Jakob Jenkov
Last update: 2016-05-20

Unit Testing Components and Factories

When unit testing the components of a larger application it can be handy sometimes to let the container (Butterfly Container) configure the components for the test. You may use the same configurations as your application runs with, or you may use test specific configurations.

Imagine you have the following container configuration:

  dataSource = 1 com.myapp.MyDataSource(
        "oracleDriverClass", "oracleUrl", "user", "password");

  personDao = * com.myapp.PersonDao(dataSource.getConnection());

Then you may have a PersonDao unit test that looks a bit like this:

public void testPersonDao(){
    IContainer           container     = new Container();
    ScriptFactoryBuilder scriptBuilder = new ScriptFactoryBuilder(container);

    FileInputStream input = new FileInputStream("containerConfig.bcs");
    scriptBuilder.addFactories(input);

    PersonDao dao = (PersonDao) container.instance("personDao");

    //test insert, update, and delete methods on the dao.
}

Rather than configuring the PersonDao by hand with dependencies (and their dependencies recursively) you just reuse the configuration of the PersonDao from the application container configuration (the file containerConfig.bcs). The more dependencies transitively a component has, the more code you save in your unit tests by obtaining the component from the container, rather than configuring the component inside the test by hand.


Replacing Factories Inside Unit Tests

You may not want to run your unit tests against Oracle, because opening and closing connections to Oracle can be very slow. Since we want to run unit tests often, they should run as fast as possible to delay our work as little as possible. Therefore you might want to run the unit tests against a faster database, like H2 Database in in-memory mode. Rather than having to copy the production configuration file and make the changes to the dataSource factory configuration, you can just replace the dataSource factory definition inside your unit test. Here is how:

public void testPersonDao(){
    IContainer           container     = new Container();
    ScriptFactoryBuilder scriptBuilder = new ScriptFactoryBuilder(container);

    FileInputStream input = new FileInputStream("containerConfig.bcs");
    scriptBuilder.addFactories(input);

    String testDataSourceDefinition =
        "dataSource = 1 com.myapp.MyDataSource(
            'h2DriverClass', 'h2Url', 'user', 'password'); ";

    scriptBuilder.replaceFactory(testDataSourceDefinition);

    PersonDao dao = (PersonDao) container.instance("personDao");

    //test insert, update, and delete methods on the dao. 
}

The lines in bold show the testDataSourceDefinition and the call to replaceFactory, which replaces the dataSource factory definition. When obtaining the PersonDao instance from the "personDao" factory, the PersonDao will now have a connection to the H2 database instead of Oracle.

Jakob Jenkov




Copyright  Jenkov Aps
Close TOC