h1. springtester

The @springtester@ module is used in conjunction with the "spring":http://www.playframework.org/modules/spring module.  Internally, it uses the "Mockito":http://code.google.com/p/mockito/ library and provides additional classes for injecting mocks/stubs when writing tests for your Play! application.

h2. Getting started

Include @springtester@ in your Play! application by adding the following in your @dependencies.yml@:

bc. - play -> springtester [version]

As @springtester@ depends on the existing Spring Play! module, you will have to include it as well:

bc. - play -> spring [version]

*Note:* @springtester@ has currently only been tested with @version 1.0.1@ of the @spring@ module.

Then update your project's dependencies to include @springtester@ and its dependencies:

bc. play deps

h2. Usage

The @springtester@ module assumes you are wiring your application using the @spring@ module.  Here is an example of two classes being wired up using the @spring@ module.  The first is a @Person@ class that injects an @AgeCalculator@ and calls the @calculate(...)@ method:

bc. @Component
public class Person {
    // Here we are injecting the AgeCalculator into the Person class
    @Resource private AgeCalculator ageCalculator;
    public boolean canVote() {
        int age = calculator.calculate("1-January-1980");
        return age >= 18;
    }
}

Note that person itself is annotated with the @Component@ annotation.  The @AgeCalculator@ will then take birth date of the @Person@ and calculate their age:

bc. @Component
public class AgeCalculator {
    public int calculate(String birthDate) {
        // some code that figures out the age of the person
    }
}

Now let's say you want to write a test for @Person@ called @PersonTest@ and wish to replace the @AgeCalculator@ with a mock that returns the age of 20 instead of calculating the actual age of the @Person@:

bc. public final class PersonTest extends SpringMockitoUnitTestCase {
    @Subject private Person subject;
    @Mock(name = "ageCalculator") AgeCalculator mockAgeCalculator;
    @Test
    public void testCanVote() throws Exception {
        Mockito.when(mockAgeCalculator.calculate("1-January-1980")).thenReturn(20);
        boolean actual = subject.canVote();
        assertEquals(true, actual);
    }
}

*How it works:*

* The @PersonTest@ extends @SpringMockitoUnitTestCase@.  This superclass does all the magic to inject mocks into your objects.

* The annotation @Subject@ will auto-magically inject the subject into the test.  In the example above, a @Person@ object will be injected into the test.  Be sure that the subject is a Spring component by annotating it with @Component.

* The annotation @Mock@ (provided by @Mockito@) is used to auto-magically create a mock of the given class.  In the example above, an @AgeCalculator@ object will be mocked and set against the field @mockAgeCalculator@.  The @Mock@ annotation can take the @name@ property which specifies the name of the field the mock will replace in the subject.  If the field name of the object to be mocked is the same as the field name in the subject, you may omit the name property like so:

bc. // The name of the mock "ageCalculator" has the same name as the
// field "ageCalculator" found in the Person class and therefore
// does not require the "name" property.
@Mock AgeCalculator ageCalculator;

* The remainder of the example test above uses @Mockito@ to mock the call to the @calculate@ method and return 20 and then asserts that the @subject.canVote()@ call will return true (since 20 is older than or equal to 18).

* The class @SpringMockitoUnitTestCase@ extends @DatabaseUnitTestCase@ which provides the helper method @checkCount(Class<? extends Model> cls, long expected)@ which can be used to check the row count of table.

* The @DatabaseUnitTestCase@ will also delete the test in-memory database before each test method to ensure a clean run for each test method execution.
