title: Integration testing Spring repository layer with DBUnit
body: <p>I have been following <a href="http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-integration-testing/" rel="nofollow">this</a> very useful blog post by Petri Kainulainen to write integration tests for my Spring repository code using spring-data-jpa and DBUnit.</p>
  
  <p>I have my bean context XML set up like so</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xmlns:jpa="http://www.springframework.org/schema/data/jpa"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
          http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"&gt;
  
      &lt;context:property-placeholder location="file:src/main/webapp/WEB-INF/config/application-test.properties"
          ignore-resource-not-found="false" /&gt;
  
      &lt;bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"&gt;
          &lt;property name="driverClass" value="${db.driver}" /&gt;
          &lt;property name="jdbcUrl" value="${db.url}" /&gt;
          &lt;property name="username" value="${db.username}" /&gt;
          &lt;property name="password" value="${db.password}" /&gt;
      &lt;/bean&gt;
      &lt;bean id="directorRepository" name="directorRepositoryMock" class="org.mockito.Mockito"
          factory-method="mock"&gt;
          &lt;constructor-arg value="com.tvfreakz.repository.DirectorRepository" /&gt;
      &lt;/bean&gt;
  
  &lt;/beans&gt;
  </code></pre>
  
  <p>My dataset XML has the following</p>
  
  <pre><code>&lt;!DOCTYPE dataset SYSTEM "my-dataset.dtd"&gt;
  &lt;dataset&gt;
      &lt;director directorid="1" director="Ridley Scott" /&gt;
      &lt;director directorid="2" director="James Cameron" /&gt;
      &lt;director directorid="3" director="David Fincher" /&gt;
      &lt;director directorid="4" director="Jean-Pierre Jeunet" /&gt;
  &lt;/dataset&gt;
  </code></pre>
  
  <p>Here's the repository interface</p>
  
  <pre><code>import org.springframework.data.jpa.repository.JpaRepository;
  import org.springframework.stereotype.Repository;
  
  import com.tvfreakz.model.entity.Director;
  
  @Repository("directorRepository")
  public interface DirectorRepository extends JpaRepository&lt;Director, Long&gt; {
  
    Director findByDirectorId(Long directorId);
  
  }
  </code></pre>
  
  <p>And my test class is set up like so</p>
  
  <pre><code>import static org.junit.Assert.assertNull;
  import static org.junit.Assert.assertEquals;
  
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.test.context.ContextConfiguration;
  import org.springframework.test.context.TestExecutionListeners;
  import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
  import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
  import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
  
  import com.github.springtestdbunit.DbUnitTestExecutionListener;
  import com.github.springtestdbunit.annotation.DatabaseSetup;
  import com.tvfreakz.model.entity.Director;
  
  @RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/config/testMVCContext.xml"})
  @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    DbUnitTestExecutionListener.class })
  @DatabaseSetup("testDataset.xml")
  public class ITDirectorRepositoryTest {
  
    @Autowired
    private DirectorRepository repository;
  
    @Test
    public void testFindByDirectorIdWhenNoDirectorFound() {
      Director director = repository.findByDirectorId(10L);
      assertNull(director);
    }
  
    @Test
    public void testFindByDirectorIdWhendirectorIsFound() {
      Director director = repository.findByDirectorId(1L);
      assertEquals("Ridley Scott", director.getDirectorName());
    }
  
  }
  </code></pre>
  
  <p>I was expecting the <code>@DatabaseSetup</code> annotation to take my configuration and set up all the tables and data inserts into my test database configured by the <code>dataSource</code> bean.</p>
  
  <p>This seemingly does nothing (i.e. the database remains blank with no tables or data) and my second test <code>testFindByDirectorIdWhendirectorIsFound</code> fails as the director returned is null. What am I missing?</p>
  
  <p><strong>EDIT 1</strong> OK I have some progress, I now have tables created, BUT no data. The issue was I shouldn't have used a mock repository. I had to update my context XML to the following. So the next issue is to try and work out why it isn't filling my newly created tables with data</p>
  
  <p><strong>EDIT 2</strong> JpaTransactionManager bean and tx annotation driven added to context</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xmlns:jpa="http://www.springframework.org/schema/data/jpa"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
          http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"&gt;
  
      &lt;context:property-placeholder location="file:src/main/webapp/WEB-INF/config/application-test.properties"
          ignore-resource-not-found="false" /&gt;
  
  &lt;jpa:repositories base-package="com.tvfreakz.repository" /&gt;
  
  &lt;bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
      &lt;property name="persistenceUnitName" value="punit"/&gt;
      &lt;property name="dataSource" ref="dataSource"/&gt;
      &lt;property name="jpaVendorAdapter"&gt;
          &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"&gt;
              &lt;property name="showSql" value="true"/&gt;
          &lt;/bean&gt;
      &lt;/property&gt;
      &lt;property name="jpaPropertyMap"&gt;
          &lt;map&gt;
              &lt;entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/&gt;
              &lt;entry key="hibernate.hbm2ddl.auto" value="update"/&gt;
              &lt;entry key="hibernate.format_sql" value="true"/&gt;
              &lt;entry key="hibernate.show_sql" value="true"/&gt;
          &lt;/map&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
      &lt;property name="entityManagerFactory" ref="entityManagerFactory"/&gt;
  &lt;/bean&gt;
  
  &lt;tx:annotation-driven transaction-manager="transactionManager"/&gt;
  
      &lt;bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"&gt;
          &lt;property name="driverClass" value="${db.driver}" /&gt;
          &lt;property name="jdbcUrl" value="${db.url}" /&gt;
          &lt;property name="username" value="${db.username}" /&gt;
          &lt;property name="password" value="${db.password}" /&gt;
      &lt;/bean&gt;
  
  &lt;/beans&gt;
  </code></pre>
  
  <p><strong>EDIT 3</strong> OK I managed to enable DEBUG level after including slf4j in my maven dependencies and creating a log4j.properties file with DEBUG level set.</p>
  
  <p>And I see this in the log, which perhaps gives a clue?</p>
  
  <pre><code>14:47:05,670  INFO TestContextManager:242 - Could not instantiate TestExecutionListener [com.github.springtestdbunit.DbUnitTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/dbunit/dataset/IDataSet]
  </code></pre>
  
  <p>I believe this is in reference to this part of my test code</p>
  
  <pre><code>@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    DbUnitTestExecutionListener.class })
  </code></pre>