@Import与@ContextConfiguration在单元测试中导入bean的区别

17

我能够使用SpringBoot 1.5.3成功地设置并运行了三个不同的测试配置

方法#1. 使用@Import注释导入Bean

@RunWith(SpringJUnit4ClassRunner.class)
@Import({MyBean.class})
public class MyBeanTest() {
    @Autowired
    private MyBean myBean;
}

方法2. 使用@ContextConfiguration注释导入Bean。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MyBean.class})
public class MyBeanTest() {
    @Autowired
    private MyBean myBean;
}

方法 #3(使用内部类配置;基于官方博客文章

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class)
public class MyBeanTest() {

    @Configuration
    static class ContextConfiguration {
        @Bean
        public MyBean myBean() {
            return new MyBean();
        }
    }

    @Autowired
    private MyBean myBean;

}

考虑到@Import注释文档

指示要导入的一个或多个{@link Configuration @Configuration}类。

以及MyBean不是配置类,而是用@Component注释的bean类,看起来方法1不正确。

来自@ContextConfiguration文档

{@code @ContextConfiguration}定义了类级别元数据,用于确定如何为集成测试加载和配置{@link org.springframework.context.ApplicationContext ApplicationContext}。

听起来更适用于单元测试,但仍应加载某种配置。

方法1和方法2更短,更简单。 方法3看起来是正确的方法。

我是对的吗?是否有其他标准,为什么我应该使用方法3,例如性能或其他原因?


MyBean是否依赖于其他的Beans?如果没有,我会像这样实例化它:MyBean myBean = new MyBean(); - Pär Nilsson
是的,它取决于 org.springframework.core.env.Environment - humkins
2个回答

2
如果您选择选项#3,则实际上不需要指定加载器。来自文档除了文档中的示例之外,如果您需要在环境中注入属性而不使用真实属性,则可以使用@TestPropertySource覆盖env。
@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from the
// static nested Config class
@ContextConfiguration
@TestPropertySource(properties = { "timezone = GMT", "port: 4242" })
public class OrderServiceTest {

    @Configuration
    static class Config {

        // this bean will be injected into the OrderServiceTest class
        @Bean
        public OrderService orderService() {
            OrderService orderService = new OrderServiceImpl();
            // set properties, etc.
            return orderService;
        }
    }

    @Autowired
    private OrderService orderService;

    @Test
    public void testOrderService() {
        // test the orderService
    }

}

0

这真的取决于你是否使用了Spring Boot提供的测试注释之一,或者你是从头开始构建上下文。Spring Framework中的核心支持要求你通过@ContextConfiguration提供“根配置”。如果你正在使用Spring Boot,则它有自己的检测要使用的根上下文的方法。默认情况下,它找到的第一个@SpringBootConfiguration注释类型。在典型的应用程序结构中,这是你应用程序包的根目录下的@SpringBootApplication

考虑到这一点,在该设置中使用@ContextConfiguration并不是一个好主意,因为它会禁用该查找,并且只会做更多的“导入bean”。

假设上下文已经为您创建,并且您想添加其他bean,则有两种主要方法:

如果您需要选择性地导入组件(在检测正确上下文的默认行为之上),那么@Import是绝对没问题的。同时,@Import的Javadoc已经过修改,明确说明导入组件是绝对没问题的,而且它并不特定于@Configuration类:

指示要导入的一个或多个组件类 - 通常是@Configuration类。

所以,方法#1绝对是正确的。
如果组件是本地测试特有的,并且您不需要将其与另一个测试共享,则可以使用内部@TestConfiguration。这也记录在参考指南中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接