September 15, 2010

Spring 3 + maven2 + Google App Engine: Part 5 [Unit test]

Unit testing is one of the most important keystones to Agile programming methodologies. Testing with maven and Spring can be a big pain, so here's a quick tutorial on how to set it up. I will not cover proper testing strategies, but I'll give you the ability to setup your own testing.

First, we'll focus on unit testing. Unit testing is easily done using the "surefire plugin". To add the plugin, edit your pom.xml file, add the following inside of the section:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <includes>
            <include>**/*Test.java</include>
        </includes>
        <excludes>
            <exclude>**/*SysTest.java</exclude>
        </excludes>
    </configuration>
</plugin>

What this does is to tell Maven that during the phase "test", to run the JUnit test using the include/exclude rules.

Next we need to create a test file to run. Luckily we can use annotations to decorate our test files making it much easier. For this example, I will create a file in the test package called EventServiceTest.java.

package com.example;
...imports...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/testApplicationContext.xml"})
public class EventServiceTest extends AbstractJUnit4SpringContextTests {

    @Autowired
    private EventService eventService;

    // Google's helper file to put all data storage in memory
    private final LocalServiceTestHelper helper =
            new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

    @Before
    public void setUp() {
        helper.setUp();
    }

    @After
    public void tearDown() {
        helper.tearDown();
    }

    @Test
    public void testCreateEvent() {
        Event event = eventService.getByName("pie day");
        assertNotNull("Pie Day should always exist!", event);
    }
}

There are a few things to notice in this example. The LocalServiceTestHelper is a class provided by Google that will allow data to be stored in memory instead of interferring with your local datastore. There are several different types of configurations and customizations that can be passed into the constructor. Visit http://code.google.com/appengine/docs/java/tools/localunittesting/javadoc/ to check out other options.

If you noticed, we are loading a new context in the @ContextConfiguration annotation. You will need to create a new context file (similar to applicationContext.xml) which usually is a copy of the applicationContext.xml file, with changes to use mock services.

I choose to specify the context file by location, which is set in my POM file to be at /src/test/resources (refer to Part 2 to see full POM file). Another option could be to use classpath scanning.

Lastly, notice that the @RunWith(SpringJUnit4ClassRunner.class), this sets up the test file for class loading.

You can now run your unit test by running the following command:
mvn test

Next post will contain information about how to create and run integration test.

1 comment:

Will said...

Maven? Unit testing? Dang, sounds like luser-ville to me... ;)