1

I have an application written using spring-REST(spring version 4.1.x and am using spring test for testing it. One of the singleton bean is caching the state so that it can be used for subsequent call in the application. This is although causing the problem when I am running multiple tests as the same bean is being used across tests and subsequent test fails. My question is how do I reset the state in the teardown? State is not accessible as its a private member of the class. Can we just remove the bean completely from the context? I am using annotated beans and autowiring wherever required.

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = ComponentTestConfig.class)
public class WebServiceComponentTest {

}

I tried to use the solution given in the following link How can i remove a singleton spring bean from ApplicationContext?

but always faiuls with no bean definition found ((BeanDefinitionRegistry) beanFactory).removeBeanDefinition("myBean");

By the way test fails only when teardown called for resetting the bean state. Bean is found while it is being used by application.

Community
  • 1
  • 1
Milind
  • 531
  • 2
  • 12
  • 24
  • Annotate your test (or the test class) with `@DirtiesContext`, this will let you start with a fresh application context. – M. Deinum Feb 02 '15 at 07:58
  • I saw in one of the stackoverflow question. This should be used rarely and it will slow down you tests. I want to avoid the degrading test performance. since it runs for every checkin as per CI pipeline... Is there a better way to fix it? – Milind Feb 02 '15 at 14:35
  • It is the only save and reliable way to achieve what you want, maybe reconsider what you have build so far and instead of using your own caching mechanism use a Spring Based caching mechanism (which you could disable for certain tests). – M. Deinum Feb 02 '15 at 14:55

2 Answers2

0

If you want more fine-grained control over your testing application context, mirror your XML config files for testing. Point your test class to only load the XML files from your test directory rather than from your WebContent directory.

That way you can totally exclude the class that is causing you problems from your test context. So your test XML might look something like this:

<context:component-scan base-package = 
    "au.com.foo.pineapple", 
    "au.com.foo.dolphin",
    "au.com.foo.controllers"
/>
<!--au.com.foo.building-->

and your WebContent XML file might look something like this:

<context:component-scan base-package =
    "au.com.foo.pineapple",
    "au.com.foo.dolphin",
    "au.com.foo.building",
    "au.com.foo.controllers"
/>
JamesENL
  • 6,400
  • 6
  • 39
  • 64
0

As M. Deinum pointed out, the safest way to achieve this is to use the @DirtiesContext annotation.

However, as also mentioned, using @DirtiesContext can result in longer test runs since the ApplicationContext will be removed from the ContextCache.

Another option -- a hack really -- is to use the ReflectionTestUtils class from spring-test to change the state of the private member in question.

Regards,

Sam (author of the Spring TestContext Framework)

Sam Brannen
  • 29,611
  • 5
  • 104
  • 136