如何推迟调用@PostConstruct,直到jUnit设置测试上下文

Posted

技术标签:

【中文标题】如何推迟调用@PostConstruct,直到jUnit设置测试上下文【英文标题】:How to defer calling @PostConstruct until jUnit has setup test context 【发布时间】:2013-10-18 03:29:58 【问题描述】:

我有一个带有受保护的 @PostConstruct 方法的静态 Spring 3.2.4 bean,该方法在初始化时从数据库加载数据。

在创建 jUnit 测试时,在我的测试方法中,我想设置数据库中的数据以适当地测试 bean。但是,鉴于 bean 在我的测试方法之前实例化,我不知道如何请求 Spring 将 bean 的实例化推迟到方法完成。

鉴于@PostConstruct 方法是受保护的,我不能直接调用它来重新初始化bean,除非我使用反射。

还有其他方法可以做到这一点,还是反射是唯一的方法? Spring 是否有任何 Util 类使其更容易,还是我必须使用标准的 java 反射?

【问题讨论】:

【参考方案1】:

您始终可以针对此类用例以编程方式启动上下文。请注意,在这种情况下,您负责上下文的生命周期。下面的伪代码说明了这一点:

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

如果这成为一个经常使用的用例,您可以创建一个模板方法来启动容器并调用回调接口。这样您就可以在一个中心位置共享上下文生命周期管理。

【讨论】:

谢谢。我最终解决了这个问题,但你的解决方案肯定给了我另一种看待它的方式。

以上是关于如何推迟调用@PostConstruct,直到jUnit设置测试上下文的主要内容,如果未能解决你的问题,请参考以下文章

如何推迟加载 UpdatePanel 内容,直到页面呈现后?

Spring4-@PostConstruct和@PreDestroy注解的使用

推迟大小计算直到 ui 呈现

如何推迟流读取调用

Mockito + Spring + @PostConstruct,mock初始化错误,为啥会调用@PostConstruct?

推迟变量分配,直到文件存在或在 Makefile 中执行规则