1

I am configuring a simple JPA application using Spring framework. My goal is to populate the db with data during JUnit Test runs. I understand this is not ideal. But I want it for different purposes.

Here is my persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    version="1.0">
    <persistence-unit name="tothought-tutorial-test" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
        <!--    <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
        <property name="hibernate.hbm2ddl.auto" value="create-drop" /> -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.show_sql" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

test-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.2.xsd">

    <!-- Database -->
    <!--  <jdbc:embedded-database id="datasource" type="H2"></jdbc:embedded-database> -->

    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/to_thought_tutorial" />
        <property name="username" value="demo" />
        <property name="password" value="demo" />
    </bean>

    <!-- Entity Manager -->
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="datasource" />
        <property name="persistenceUnitName" value="tothought-tutorial-test" />
    </bean>

    <!-- Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <!-- Jpa Repositories -->
    <jpa:repositories base-package="com.cloudfoundry.tothought.repositories"></jpa:repositories>
</beans>

Here is junitTest class

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:META-INF/test-context.xml")
@Transactional
public class PostPartRepositoryTest {

    @Autowired
    PostPartRepository repository;

    @Test
    public void test() {
        PostPart postPart = new PostPart();
        String body = "Hello";
        postPart.setBody(body);

        repository.save(postPart);

        PostPart dbPostPart = repository.findOne(postPart.getPostPartId());
        assertNotNull(dbPostPart);
        assertEquals(body, dbPostPart.getBody());
    }

    @Test
    public void insertTest(){

        Post post = new Post();
        post.setPostDate(new Date());
        post.setTitle("First Post");

        PostPart postPart = new PostPart();
        String body = "Hello";
        postPart.setBody(body);

        postPart.setPost(post);

        repository.save(postPart);

        PostPart dbPostPart = repository.findOne(postPart.getPostPartId());
        assertNotNull(dbPostPart);
        assertNotNull(dbPostPart.getPost());
        assertEquals(body, dbPostPart.getBody());
    }

}

Both the test passes. But I do not see any entry in tables, although tables are created the first time.

brain storm
  • 30,124
  • 69
  • 225
  • 393

1 Answers1

2

You won't see any entries because you are running the test with @Transactional using the SpringJUnit4ClassRunner. The default for running tests with @Transactional is for any database changes to be automatically rolled back once the test is finished. For more information see this question here

The order in which these things happen is as follows:

  1. Test starts, setup scripts are run, which creates your tables.
  2. Tests start running in transactional context.
  3. Tests finish running, and any database changes made during your test, are automatically rolled back, leaving the database in the state it was in before the tests ran.

You can change this default behaviour you can use @TransactionConfiguration(defaultRollback=false) at the top of the class. However this is bad practice because unit tests should not depend on each other and shouldn't be permanently modifying application state. Also, if you are depending on one test to set something in the environment and use it in the next test, there is no guarantee which order the tests are executed by test runner.

Community
  • 1
  • 1
JamesENL
  • 6,400
  • 6
  • 39
  • 64