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:
- Autowiring skips some beans
- 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 f开发者_JAVA技巧ollowing 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.
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.
精彩评论