java - 是否可以编写测试事务代码的事务单元测试?

标签 java spring unit-testing transactions aop

我正在使用 Spring 编写一个应用程序。我想将 JDBC 代码编写为事务性的,这可以通过使用 AOP 来实现:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="get*" read-only="true" rollback-for="MyCustomException"/>
        <tx:method name="*" rollback-for="MyCustomException" />
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="pc" expression="execution(* com.me.jdbc.*.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pc" />
</aop:config>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
    <constructor-arg ref="simpleDataSource" />
</bean>

<bean id="simpleDataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
    <property name="driverClass" value="org.h2.Driver" />
    <property name="username" value="sa" />
    <property name="password" value="" />
    <property name="url" value="jdbc:h2:mem:aas;MODE=Oracle;DB_CLOSE_DELAY=-1;MVCC=true" />
</bean>

因此,如果发生 MyCustomException,com.me.jdbc 中的所有方法都应该是事务性的并回滚。到目前为止,这有效。

我现在想编写一个单元测试,但我希望我的单元测试是事务性的,这样,一旦测试完成,整个事务将回滚并使数据库保持开始时的状态。

我可以通过声明来实现这一点:

@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class })
@Transactional

在我的测试课上。然而问题是我丢失了应用程序代码上的事务,即每次测试后事务都会回滚,但是如果应用程序代码中发生异常,则插入不会回滚并且我的单元测试失败,因为我希望表是空的,但它不是。

我将如何实现这两个级别的事务?是否可以?我可以通过为单元测试编写一个设置方法来解决这个问题,该方法在每次测试之前清除所有表。我对此很满意,但我认为能够使用回滚方法来实现相同的目标会很好。

最佳答案

正如评论部分中所发布的,问题在于,通过使测试方法封装事务,只有在测试抛出异常时才会发生回滚。这使得在抛出异常之前无法验证被测行为。我采用的方法是清空设置方法中的所有表(在每次测试之前)。

关于java - 是否可以编写测试事务代码的事务单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21493560/

相关文章:

java - 无法解析符号org.springframework.test.web.server

java - 在对类方法进行单元测试时模拟子类的方法

visual-studio - 无效COMObjectException : COM object that has been separated from its underlying RCW cannot be used?

ios - 框架架构 : Specify NSBundle to load . 来自单例初始化期间的 plist 文件

java - java.io.Serializable 的 C/C++ 等价物是什么?

java - 时区数据更新程序(Java) 至 tzdata2016e

java - 将Netbeans中依赖的maven项目中的代码更改热部署到tomcat

java - maven-jar-plugin 中的 NPE

java - 如何最好地使用 spring 在基于 Java 的系统中接收电子邮件?

java - 如何配置 Spring-WS 以使用 JAXB Marshaller?