ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-在Spring集成测试期间刷新/重建特定的bean

2019-11-08 13:20:49  阅读:832  来源: 互联网

标签:spring-boot junit integration-testing spring java


我们现有的Spring Boot集成设置使用@DirtiesContext在不同的测试方法之间重建整个bean池.

这是相当慢的,所以我们开始使用可以“刷新”或在内部拆除/重建的Bean,而无需重新创建实例.

问题是只有一些bean支持此功能.如果我们控制UsersBean,则可以实现UsersBean.refresh()方法并在我们的@After方法中调用它.

但是,如果我们有不支持刷新或无法控制的现有bean /类,我们如何有条件地指示在特定测试后需要对某些bean进行污染/重建?

或更简洁地说:在测试方法结束时,是否有一种方法可以将Bean池的一个子区域标记为肮脏,以进行重建?

解决方法:

看来这是可能的,至少在Spring Boot环境中如此. ApplicationContext实现有一个GenericApplicationContext,它具有removeBeanDefinition()的功能,然后可以通过registerBeanDefinition()重新注册.

甚至通过层叠来删除包含对要删除的bean的引用的bean(此实现可以在DefaultSingletonBeanRegistry.destroyBean()中看到).

例如,如果Bean1被Bean2引用:

@Component
public class Bean1 {

}

@Component
public class Bean2 {
    @Autowired
    public Bean1 bean1;
}

然后测试可以从上下文中删除bean1,并看到bean2也被替换了:

@RunWith(SpringRunner.class)
public class BeanRemovalTest implements ApplicationContextAware {
    @Autowired
    private Bean1 bean1;

    @Autowired
    private Bean2 bean2;

    private ApplicationContext applicationContext;

    @Test
    public void test1() throws Exception {
        System.out.println("test1():");
        System.out.println("  bean1=" + bean1);
        System.out.println("  bean2.bean1=" + bean2.bean1);

        resetBean("bean1");
    }

    @Test
    public void test2() throws Exception {
        System.out.println("test2():");
        System.out.println("  bean1=" + bean1);
        System.out.println("  bean2.bean1=" + bean2.bean1);
    }

    private void resetBean(String beanName) {
        GenericApplicationContext genericApplicationContext = (GenericApplicationContext) applicationContext;
        BeanDefinition bd = genericApplicationContext
                .getBeanDefinition(beanName);
        genericApplicationContext.removeBeanDefinition("bean1");
        genericApplicationContext.registerBeanDefinition("bean1", bd);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }
}

这显示了两个被替换的bean实例:

test1():
  bean1=hello.so.Bean1@61d6015a
  bean2.bean1=hello.so.Bean1@61d6015a

test2():
  bean1=hello.so.Bean1@2e570ded
  bean2.bean1=hello.so.Bean1@2e570ded

(如果将resetBean(“ bean1”)注释掉,则两次都是同一实例).

一定会有一些无法解决的问题-例如如果另一个bean持有从ApplicationContext.getBean()获得的引用.

标签:spring-boot,junit,integration-testing,spring,java
来源: https://codeday.me/bug/20191108/2007926.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有