Spring JUnit 测试:自动装配和事务问题

发布于 2024-10-12 20:48:51 字数 2394 浏览 2 评论 0原文

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

  • WAS 7.0
  • Java 6
  • Spring 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 不会代理事务

Item 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 中尝试过,但似乎没有帮助。

感谢您的任何帮助。

We have an existing Java EE application that leverages Spring and are transitioning from xml configuration to autowiring. We just converted most of our EJBs to Spring beans, but currently still use MDBs and EJB timers.

  • WAS 7.0
  • Java 6
  • Spring 3.0.5
  • JUnit 4.8.1

I am also in the process of writing integration tests in JUnit. My integration tests use most of the context configuration files as when running in WAS, but not things that tie into JNDI or use the JTA transaction manager. For those, I have equivalents that setup ActiveMQ queues, a Hibernate transaction manager, etc.

My test looks like this:

@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();
    }
}

My tests are having problems for at least a couple of reasons:

  1. Autowiring skips some beans
  2. Sometimes beans are not proxied for transactions

Item 1 seems to have something to do with circular references. I made copies of some of the beans that had autowiring problems. I made the copies in the same package. The copy gets wired up, but not the original. I then began to move references in the xml context files from the original to the copy, and at some point, the copy no longer gets wired but the original does. I have the following in one of the context files (with the names changed to protect me :):

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

<context:annotation-config />

I think the second entity is redundant, but should be innocuous.

I don't see any errors in the logs. I turned logging to debug and see most of the beans being autowired, but no errors on those Spring seems to skip.

Item 2 might be related to Item 1. Some beans are not properly proxied to handle transactions. In my JUnit-only context, I have the following:

<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>

I am getting hibernate errors in some places because there is no transaction, while in other places, the beans are proxied and transactions are started. Both the proxied and non-proxied beans are in subpackages of com.mycompany.package1.

Of course, all of this works when we run the application in WAS. It uses a ContextSingletonBeanFactoryLocator. I tried that as well in JUnit, but it has not seemed to help.

Thanks for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萧瑟寒风 2024-10-19 20:48:51

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

AbstractTransactionalJUnit4SpringContextTests

然后您可以使用以下内容配置事务内容:

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

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

I think your test class should extend from:

AbstractTransactionalJUnit4SpringContextTests

and then you can configure the transactional stuff with:

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

where defaultRollback defines whether to rollback after every test.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文