gpt4 book ai didi

java - 使用 Spring transactionManager 进行集成测试

转载 作者:行者123 更新时间:2023-11-29 05:22:09 25 4
gpt4 key购买 nike

我已经为此苦苦思索了一段时间,并且有一种我忽略了一些愚蠢的事情的沮丧感觉。我正在尝试使用事务管理器进行非常简单的集成测试,但似乎无法像我认为的那样让它回滚。

被测类:

public class JdbcUserDAO implements UserDAO {

@Autowired
private DataSource dataSource;

private static final String TERM_USER_SQL =
"UPDATE USER " +
"SET TERM_DATE = date('now') " +
"WHERE USER_NAME = ?";

@Override
public void terminateUser(String userName) {

try (Connection conn = dataSource.getConnection()){
PreparedStatement stmt = conn.prepareStatement(TERM_USER_SQL);
stmt.setString(1, userName);
stmt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Caught SQLException in persistence service", e);
}
}

Spring 上下文(applicationContext.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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<tx:annotation-driven/>
<bean id="userDAO" class="com.mycompany.persistence.dao.impl.JdbcUserDAO"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.sqlite.JDBC"/>
<property name="url" value="jdbc:sqlite:C:\\development.sqlite3"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml"})
@TransactionConfiguration
@Transactional
public class JdbcUserDAOTest {

@Autowired
private UserDAO userDAO;

@Test
public void test_terminateUser() {
userDAO.terminateUser("USERNAME");
}
}

据我所知,TransactionConfiguration 的 defaultRollback 行为是“true”,默认的 transactionManager bean 名称是“transactionManager”,所以我应该设置在那里。我运行此测试并期望“TERM_DATE”列在测试完成后恢复为“null”(它的起始值),但事实并非如此(我在测试完成后查询并且可以看到它仍然 = 今天的日期)。

我什至得到了看起来非常有前途的日志记录:

Jun 17, 2014 1:25:48 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction
INFO: Began transaction (1): transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@10279954]; rollback [true]
Jun 17, 2014 1:25:48 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction
INFO: Rolled back transaction after test execution for test context [TestContext@41cbd50f testClass = JdbcUserDAOTest, testInstance = com.mycompany.persistence.dao.JdbcUserDAOTest@2d10ed88, testMethod = test_terminateUser@JdbcUserDAOTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@325a92d5 testClass = JdbcUserDAOTest, locations = '{classpath:/applicationContext.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
Jun 17, 2014 1:25:48 PM org.springframework.context.support.GenericApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericApplicationContext@3304e92a: startup date [Tue Jun 17 13:25:48 MDT 2014]; root of context hierarchy

我到底忽略了什么???非常感谢。

如果有帮助,相关的 POM 依赖项如下所示:

<dependencies>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.7.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.2.9.RELEASE</spring.version>
</properties>

最佳答案

如果您使用的是 Spring,请不要编写样板 JDBC 代码。

相反,使用 Spring 的 JdbcTemplate,它会自动处理当前 Spring 管理的事务消除所有样板 JDBC 代码。

你应该用这样的东西替换你的整个 DAO 实现:

public class JdbcUserDAO {

private static final String TERM_USER_SQL = "UPDATE USER "
+ "SET TERM_DATE = date('now') WHERE USER_NAME = ?";

private final JdbcTemplate jdbcTemplate;

@Autowired
public JdbcUserDAO(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}

public void terminateUser(String userName) {
jdbcTemplate.update(TERM_USER_SQL, userName);
}

}

问候,

山姆

关于java - 使用 Spring transactionManager 进行集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24272239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com