# Testing

## Introduction

The Spring team considers developer testing to be an absolutely integral part of enterprise software development. A thorough treatment of testing in the enterprise is beyond the scope of this chapter; rather, the focus here is on the value add that the adoption of the IoC principle can bring to unit testing; and on the benefits that the Spring Framework provides in integration testing.

## Unit testing

One of the main benefits of Dependency Injection is that your code is much less likely to have any hidden dependencies on the runtime environment or other configuration subsystems. This allows for unit tests to be written in a manner such that the object under test can be simply instantiated with the `new` operator and have its dependences set in the unit test code. You can use mock objects (in conjunction with many other valuable testing techniques) to test your code in isolation. If you follow the architecture recommendations around Spring you will find that the resulting clean layering and componentization of your codebase will naturally faciliate easier unit testing. For example, you will be able to test service layer objects by stubbing or mocking DAO interfaces, without any need to access persistent data while running unit tests.

True unit tests typically will run extremely quickly, as there is no runtime infrastructure to set up, i.e., database, ORM tool, or whatever. Thus emphasizing true unit tests as part of your development methodology will boost your productivity. The upshot of this is that you do not need this section of the testing chapter to help you write effective unit tests for your IoC-based applications.

## Integration testing

However, it is also important to be able to perform some integration testing enabling you to test things such as:

- The correct wiring of your Spring IoC container contexts.

- Data access using ADO.NET or an ORM tool. This would include such things such as the correctness of SQL statements / or NHibernate XML mapping files.

The Spring Framework provides support for integration testing when using NUnit and Microsoft's Testing framework 'MSTest'. The NUnit classses are located in the assembly `Spring.Testing.NUnit.dll` and the MSTest is located in `Spring.Testing.Microsoft.dll`.

The `Spring.Testing.NUnit.dll` library is compiled against NUnit 2.5.1. Note that test runners integrated inside VS.NET may or may not support this version. At the time of this writing Reshaper 4.5.0 did not properly support NUnit 2.5.1. To use Resharper with NUnit 2.5.1 you need to download 4.5.1 RC2 or later.

These namespaces provides NUnit and MSTest superclasses for integration testing using a Spring container.

These superclasses provide the following functionality:

- Spring IoC container caching between test case execution.

- The pretty-much-transparent Dependency Injection of test fixture instances (this is nice).

- Transaction management appropriate to integration testing (this is even nicer).

- A number of Spring-specific inherited instance variables that are really useful when integration testing.

### Context management and caching

The ``Spring.Testing.NUnit`` and `Spring.Testing.Microsoft` namespace provides support for consistent loading of Spring contexts, and caching of loaded contexts. Similarly Spring.TestingSupport for the caching of loaded contexts is important, because if you are working on a large project, startup time may become an issue - not because of the overhead of Spring itself, but because the objects instantiated by the Spring container will themselves take time to instantiate. For example, a project with 50-100 NHibernate mapping files might take 10-20 seconds to load the mapping files, and incurring that cost before running every single test case in every single test fixture will lead to slower overall test runs that could reduce productivity.

To address this issue, the `AbstractDependencyInjectionSpringContextTests` has an `protected` property that subclasses must implement to provide the location of context definition files:

    protected abstract string[] ConfigLocations { get; }

Implementations of this method must provide an array containing the IResource locations of XML configuration metadata used to configure the application. This will be the same, or nearly the same, as the list of configuration locations specified in `App.config/Web.config` or other deployment configuration.

By default, once loaded, the configuration file set will be reused for each test case. Thus the setup cost will be incurred only once (per test fixture), and subsequent test execution will be much faster. In the unlikely case that a test may 'dirty' the config location, requiring reloading - for example, by changing an object definition or the state of an application object - you can call the `SetDirty()` method on `AbstractDependencyInjectionSpringContextTests` to cause the test fixture to reload the configurations and rebuild the application context before executing the next test case.

### Dependency Injection of test fixtures

When `AbstractDependencyInjectionSpringContextTests` (and subclasses) load your application context, they can optionally configure instances of your test classes by Setter Injection. All you need to do is to define instance variables and the corresponding setters. `AbstractDependencyInjectionSpringContextTests` will automatically locate the corresponding object in the set of configuration files specified in the `ConfigLocations` property.

Consider the scenario where we have a class, `HibernateTitleDao`, that performs data access logic for say, the `Title` domain object. We want to write integration tests that test all of the following areas:

- The Spring configuration; basically, is everything related to the configuration of the `HibernateTitleDao` object correct and present?

- The Hibernate mapping file configuration; is everything mapped correctly and are the correct lazy-loading settings in place?

- The logic of the `HibernateTitleDao`; does the configured instance of this class perform as anticipated?

Let's look at the NUnit test class itself (we will look at the configuration immediately afterwards).

    /// Using NUnit

    [TestFixture]
    public class HibernateTitleDaoTests : AbstractDependencyInjectionSpringContextTests  {

        // this instance will be (automatically) dependency injected
        private HibernateTitleDao titleDao;

        // a setter method to enable DI of the 'titleDao' instance variable
        public HibernateTitleDao HibernateTitleDao {
            set { titleDao = value; }
        }

        [Test]
        public void LoadTitle() {
            Title title = this.titleDao.LoadTitle(10);
            Assert.IsNotNull(title);
        }

        // specifies the Spring configuration to load for this test fixture
        protected override string[] ConfigLocations {
            return new String[] { "assembly://MyAssembly/MyNamespace/daos.xml" };
        }

    }

The file referenced by the ConfigLocations method (`'classpath:com/foo/daos.xml'`) looks like this:

    <?xml version="1.0" encoding="utf-8" ?>
    <objects  xmlns="http://www.springframework.net">

        <!-- this object will be injected into the HibernateTitleDaoTests class -->
        <object id="titleDao" type="Spring.Samples.HibernateTitleDao, Spring.Samples">
            <property name="sessionFactory" ref="sessionFactory"/>
        </object>

        <object id="sessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate">
            <!-- dependencies elided for clarity -->
        </object>

    </objects>

The `AbstractDependencyInjectionSpringContextTests` classes uses autowire by type. Thus if you have multiple object definitions of the same type, you cannot rely on this approach for those particular object. In that case, you can use the inherited `applicationContext` instance variable, and explicit lookup using (for example) an explicit call to `applicationContext.GetObject("titleDao")`.

Using AbstractDependencyInjectionSpringContextTests with MSTest is very similar.

    /// Using Microsoft's Testing Framework

    [TestClass]
    public class HibernateTitleDaoTests : AbstractDependencyInjectionSpringContextTests  {

        // this instance will be (automatically) dependency injected
        private HibernateTitleDao titleDao;

        // a setter method to enable DI of the 'titleDao' instance variable
        public HibernateTitleDao HibernateTitleDao {
            set { titleDao = value; }
        }

        [Test]
        public void LoadTitle() {
            Title title = this.titleDao.LoadTitle(10);
            Assert.IsNotNull(title);
        }

        // specifies the Spring configuration to load for this test fixture
        protected override string[] ConfigLocations {
            return new String[] { "assembly://MyAssembly/MyNamespace/daos.xml" };
        }

    }

If you don't want dependency injection applied to your test cases, simply don't declare any set properties. Alternatively, you can extend the `AbstractSpringContextTests` - the root of the class hierarchy in the `Spring.Testing.NUnit` and `Spring.Testing.Microsoft` namespaces. It merely contains convenience methods to load Spring contexts, and performs no Dependency Injection of the test fixture.

#### Field level injection

If, for whatever reason, you don't fancy having setter properties in your test fixtures, Spring can (in this one case) inject dependencies into `protected` fields. Find below a reworking of the previous example to use field level injection (the Spring XML configuration does not need to change, merely the test fixture).

    [TestFixture]
    public class HibernateTitleDaoTests : AbstractDependencyInjectionSpringContextTests{

        public HibernateTitleDaoTests() {
        	   // switch on field level injection
            PopulateProtectedVariables = true;
        }

        // this instance will be (automatically) dependency injected
        protected HibernateTitleDao titleDao;

        [TestMethod]
        public void LoadTitle() {
            Title title = this.titleDao.LoadTitle(10);
            Assert.IsNotNull(title);
        }

        // specifies the Spring configuration to load for this test fixture
        protected override string[] ConfigLocations {
            return new String[] { "assembly://MyAssembly/MyNamespace/daos.xml" };
        }

    }

In the case of field injection, there is no autowiring going on: the name of your `protected` instances variable(s) are used as the lookup object name in the configured Spring container.

### Transaction management

One common issue in tests that access a real database is their effect on the state of the persistence store. Even when you're using a development database, changes to the state may affect future tests. Also, many operations - such as inserting to or modifying persistent data - cannot be done (or verified) outside a transaction.

The `AbstractTransactionalDbProviderSpringContextTests` superclass (and subclasses) exist to meet this need. By default, they create and roll back a transaction for each test. You simply write code that can assume the existence of a transaction. If you call transactionally proxied objects in your tests, they will behave correctly, according to their transactional semantics.

`AbstractTransactionalSpringContextTests` depends on a `IPlatformTransactionManager` object being defined in the application context. The name doesn't matter, due to the use of autowire by type.

Typically you will extend the subclass, `AbstractTransactionalDbProviderSpringContextTests`. This also requires that a `DbProvider` object definition - again, with any name - be present in the configurations. It creates an `AdoTemplate` instance variable that is useful for convenient querying, and provides handy methods to delete the contents of selected tables (remember that the transaction will roll back by default, so this is safe to do).

If you want a transaction to commit - unusual, but occasionally useful when you want a particular test to populate the database - you can call the `SetComplete()` method inherited from `AbstractTransactionalSpringContextTests`. This will cause the transaction to commit instead of roll back.

There is also convenient ability to end a transaction before the test case ends, through calling the `EndTransaction()` method. This will roll back the transaction by default, and commit it only if `SetComplete()` had previously been called. This functionality is useful if you want to test the behavior of 'disconnected' data objects, such as Hibernate-mapped objects that will be used in a web or remoting tier outside a transaction. Often, lazy loading errors are discovered only through UI testing; if you call `EndTransaction()` you can ensure correct operation of the UI through your NUnit test suite.

### Convenience variables

When you extend the `AbstractTransactionalDbProviderSpringContextTests` class you will have access to the following `protected` instance variables:

- `applicationContext` (a `IConfigurableApplicationContext`): inherited from the `AbstractDependencyInjectionSpringContextTests` superclass. Use this to perform explicit object lookup, or test the state of the context as a whole.

- `adoTemplate`: inherited from `AbstractTransactionalDbProviderSpringContextTests`. Useful for querying to confirm state. For example, you might query before and after testing application code that creates an object and persists it using an ORM tool, to verify that the data appears in the database. (Spring will ensure that the query runs in the scope of the same transaction.) You will need to tell your ORM tool to 'flush' its changes for this to work correctly, for example using the `Flush()` method on NHibernate's `ISession` interface.

Often you will provide an application-wide superclass for integration tests that provides further useful instance variables used in many tests.