我有一个带有受保护的@PostConstruct方法的静态Spring 3.2.4 bean,它在初始化时从数据库加载数据。
在创建jUnit测试时,在我的测试方法中,我想在DB中设置数据以适当地测试bean。但是,鉴于bean在我的测试方法之前被实例化,我不知道如何在方法完成之前请求Spring推迟bean的实例化。
鉴于@PostConstruct方法受到保护,我不能直接调用它来重新初始化bean,除非我使用反射。
还有另一种方法可以做到这一点,还是反思唯一的方法? Spring是否有任何Util类可以使它更容易,还是我必须使用标准的java反射?
答案 0 :(得分:2)
您始终可以以编程方式为此类用例启动上下文。请注意,在这种情况下,您负责上下文的生命周期。以下伪代码说明了这一点:
@Test
public void yourTest() {
// setup your database
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("/org/foo/your-context.xml");
// Or new AnnotationConfigApplicationContext(YourConfig.class)
try {
YourBean bean = context.getBean("beanId");
// Assertions
} finally {
context.close();
}
}
您可能需要Spring来初始化您的数据库。例如,您可以使用常规的Spring测试上下文支持来初始化数据库设置所需的bean,并以编程方式启动另一个上下文来断言您的服务。如果该上下文需要一些用于数据库初始化的服务,则可以启动子上下文,例如
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration // for instance FooTest-context.xml
public class FooTest {
@Autowired
private ApplicationContext mainContext;
@Test
public void yourTest() {
// setup your database
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext();
context.setParent(mainContext);
context.setConfigLocation("/org/foo/your-context.xml");
context.refresh();
try {
YourBean bean = context.getBean("beanId");
// Assertions
} finally {
context.close();
}
}
}
如果它成为一个循环用例,您可以创建一个启动容器并调用回调接口的模板方法。这样,您就可以在中心位置共享上下文生命周期管理。