【问题标题】:Spring JUnit Testing: Autowiring and Transaction ProblemsSpring JUnit 测试:自动装配和事务问题
【发布时间】:2011-06-10 12:59:20
【问题描述】:

我们有一个现有的 Java EE 应用程序,它利用 Spring 并正在从 xml 配置过渡到自动装配。我们刚刚将大部分 EJB 转换为 Spring bean,但目前仍在使用 MDB 和 EJB 计时器。

  • 是 7.0
  • Java 6
  • 春季 3.0.5
  • JUnit 4.8.1

我也在用 JUnit 编写集成测试。我的集成测试使用在 WAS 中运行时的大多数上下文配置文件,但不使用与 JNDI 相关的东西或使用 JTA 事务管理器。对于那些,我有设置 ActiveMQ 队列、Hibernate 事务管理器等的等价物。

我的测试如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/junit-container-context.xml",
    "/spring-contexts/service-context.xml",
    "/spring-contexts/integration-context.xml",
    "/available-tests-context.xml" })
public class TestCase1Runner {

    @Autowired
    TestCase1 test;

    @Autowired
    private ApplicationContext applicationContext;

    @Before
    public void setupErrorHandling() {
        // Some setup
    }

    @Test
    @Transactional
    public void run() throws Exception {
        test.executeTest();
    }
}

我的测试出现问题至少有几个原因:

  1. 自动装配会跳过一些 bean
  2. 有时 bean 不会被代理用于事务

第 1 项似乎与循环引用有关。我复制了一些有自动装配问题的 bean。我在同一个包中制作了副本。副本被连接起来,但不是原件。然后,我开始将 xml 上下文文件中的引用从原始文件移动到副本,并且在某些时候,副本不再连接,但原始文件会连接。我在其中一个上下文文件中有以下内容(更改了名称以保护我:):

<context:component-scan
    base-package="com.mycompany.package1,com.mycompany.package2" />

<context:annotation-config />

我认为第二个实体是多余的,但应该是无害的。

我在日志中看不到任何错误。我将日志记录转为调试,并看到大多数 bean 正在自动装配,但这些 Spring 似乎没有任何错误跳过。

第 2 项可能与第 1 项相关。某些 bean 未正确代理以处理事务。在我的纯 JUnit 上下文中,我有以下内容:

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="servicePointcut"
        expression="execution(public * com.mycompany.package1..*.*(..))" />

    <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut" />
</aop:config>

由于没有事务,我在某些地方遇到休眠错误,而在其他地方,bean 被代理并开始事务。代理和非代理 bean 都在 com.mycompany.package1 的子包中。

当然,当我们在 WAS 中运行应用程序时,所有这些都有效。它使用 ContextSingletonBeanFactoryLocator。我在 JUnit 中也尝试过,但似乎没有帮助。

感谢您的帮助。

【问题讨论】:

    标签: spring junit autowired


    【解决方案1】:

    我认为您的测试类应该扩展自:

    AbstractTransactionalJUnit4SpringContextTests
    

    然后你可以配置事务性的东西:

    @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
    

    defaultRollback 定义是否在每次测试后回滚。

    【讨论】:

    • 我确实发现了这个问题。我有一个 PropertyOverrideConfigurer。与覆盖匹配的 bean 是未代理的 bean。所以我注释掉了覆盖文件中的值,这使得一切都按预期工作。
    猜你喜欢
    • 2011-04-09
    • 2015-03-03
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 2020-02-09
    • 1970-01-01
    相关资源
    最近更新 更多