I have a MySQL database created and filled with test-purpose rows. I want to do my DAO unit tests on this database. Each @Test
is @Transactional
so a rollback is done after each test. Unfortunately, it is not working as changes are still made to my database.
I'm loading my Spring configuration with the following context.xml
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd"
xmlns:tx="http://www.springframework.org/schema/tx">
<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/push_test" />
<property name="username" value="push_dao" />
<property name="password" value="pushpassword" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="userPushDAO" class="my.package.userPushDAOImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
This stackoverflow issue said that I
must provide a
PlatformTransactionManager
bean in the application context
But even with it (it's the transactionManager
in my context) nothing happens, my database is still modified and not rollbacked.
Here is my DAO test class
public class UtilisateurPushDAOImplTest {
private static ApplicationContext ctx;
private static UserPushDAO userPushDAO;
@BeforeClass
public static void doSetup() {
ctx = new ClassPathXmlApplicationContext("context.xml");
userPushDAO = (userPushDAO) ctx.getBean("userPushDAO");
}
@Test
@Transactional
public void test() {
userPushDAO.deleteById("id");
}
}
Am I missing something in my configuration or in my comprehension on how/what @Transactional
should work/do ?
As @M.Deinum posted in the comment section,
@Transactional
on tests will only work with theSpringRunner
as a Unit test runner.It doesn't work if you create the application context yourself.
Also don't forget to add the transaction schema into the context.xml
to be able to load your context file correctly.
DAO test class
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/context.xml"})
public class UserPushDAOImplTest {
@Resource(name="userPushDAO")
private UserPushDAO userPushDAO;
@Test
@Transactional
public void test() {
userPushDAO.deleteById("id");
}
}
context.xml
<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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<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/push_test" />
<property name="username" value="push_dao" />
<property name="password" value="pushpassword" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="userPushDAO" class="my.package.userPushDAOImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>