Integration Testing in a Spring Project

February 20, 2014 Colin Shield

We love testing here at Pivotal Labs. Every pair on every project at some point asks the question, “So how are we going to test this?” If our testing strategy includes access to a data layer then it is important to know the state of the data before our tests run. In rspec this is often achieved by wrapping each test around a database transaction. If that isn’t possible (maybe the test code doesn’t have access to the DB connection) then a database cleaning strategy is often used. This strategy often truncates database tables between tests.

Here are two well-used integration testing techniques in the Spring world. The first uses transaction, the second a database clean.

Spring MVC Test Framework
The first is the Spring MVC Test Framework. This test framework does not require running a servlet container. This means that view from JSPs are not rendered at all. Other rendering such as Velocity will render views. A useful feature is the ability to wrap individual tests in transactions with annotations. Here is an example of a simple get request test wrapped in a transaction. These tests are comparable to controller tests in the Rails world.

@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
public class AppTest {
    private MockMvc mockMvc;
    protected WebApplicationContext wac;

    public void setup() {
        this.mockMvc = webAppContextSetup(this.wac).build();
    public void simple() throws Exception {

HtmlUnit involves running a full application server and executing tests against the running server. This means that views are rendered and their content’s can be checked. These tests are very similar to our rspec integration tests written using cabybara. This test fills in some values to a form, submits it and checks that the page updates with the entered form data. As the tests run against an already running application server we can’t wrap the tests in a transaction. As we’re using flyway for database migrations this allows us to use a @FlywayTest annotation on our tests in order to run each test against a clean DB. Much like database cleaner in the rails testing world; the DB is cleaned and re-created after each test. The same Spring context configuration is used as for the application server that we are running tests against. Notice the @FlywayTest annotation on the test class. We had to use the spring4 branch from flyway-test-extenstions.

@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, FlywayTestExecutionListener.class })
public class FormTest {
    public void postForm() throws Exception {
        final WebClient webClient = new WebClient();
        final HtmlPage page = webClient.getPage("http://localhost:3000/");
        final HtmlForm form = page.getFormByName("user");
        final HtmlSubmitInput button = form.getInputByValue("Add User");
        final HtmlTextInput firstName = form.getInputByName("firstName");
        final HtmlTextInput lastName = form.getInputByName("lastName");
        final HtmlTextInput email = form.getInputByName("email");
        final HtmlPage page2 =;


This tactic of re-running migrations after every test will certainly slow down test execution as more migrations are added. Compressing the migrations down periodically will help with this.

About the Author


Decoupling JS from the DOM
Decoupling JS from the DOM

There has been a big shift in the last few years toward javascript frameworks that dictate how we deal with...

A Preview of MWC 2014
A Preview of MWC 2014

It’s that time of year again! From February 24-27, we’ll be at Fira Gran Via in Barcelona for Mobile World ...

SpringOne. Catch all the highlights

Watch now