Spring 4 upgrade now junit tests fails on “Generic

2019-07-26 22:35发布

问题:

I have a spring web app that connects to some jms message brokers and am now finding test errors and failures after migrating from Spring 3.2.16 to Spring 4.2.4.RELEASE.

The error below is what I am now getting after simply changing the spring version on unit tests that use JmsTemplate.

 org.springframework.context.support.GenericApplicationContext@12eec522 has not been refreshed yet

The test classes are configured like so:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:beans.xml"})
public class JMSMiscUtilTest {

Ultimately, there are multiple unit tests in this class and a couple other similar classes that test code which attempts to register beans with a GenericApplicationContext.

These methods make calls on the GenericApplicationContext (JmsTemplate)genericContext.getBean(location);

and then subsequently attempt to register beans like so:

final BeanDefinitionBuilder bDBuilder = BeanDefinitionBuilder
                .rootBeanDefinition("org.springframework.jms.core.JmsTemplate");
genericContext.registerBeanDefinition(location,
                bDBuilder.getBeanDefinition());

It seems to me that these tests attempt to use beans it's registered with the bean definition builder before it's finished registering all of the beans it tries to load into the genericApplicationContext.

This must have been allowed in the spring 3 but not 4.

How can I refactor this code to remain using a GenericApplicationContext, or take a different approach?

________Edit:____________

The app also has many beans defined in XML which I still need through out the entire run time of the application. Calling context.refresh() like the error indicates fixes the "has not been refreshed" error, but then when the app subsequently tries to use one of the beans defined in XML, it throws an error that it does not exist because it was wiped from the context from the .refresh call.

回答1:

After registering beans dynamically you have to call context.refresh() before acessing the context again.

So after you made calls to registerBeanDefinition(..), call also context.refresh().

As far as I now, this behaviour did not change from Spring 3 to 4. What indeed may have changed is the way how/when spring refreshes the context after every test method or test class. You can try to change this using @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)