如何在SpringBootTest中添加bean

时间:2019-09-03 13:02:40

标签: java spring spring-boot unit-testing

这个问题似乎非常简单,但是奇怪的是我没有找到解决方法。

我的问题是关于在SpringBootTest中添加/声明一个bean,而不是覆盖一个bean,也不是使用嘲笑来模拟一个bean。

这是我尝试以最简单的方式实现实际需求时得到的内容(但这不起作用):

一些服务,bean和配置:

@Value // lombok
public class MyService {
    private String name;
}

@Value // lombok
public class MyClass {
    private MyService monitoring;
}

@Configuration
public class SomeSpringConfig {

    @Bean
    public MyClass makeMyClass(MyService monitoring){
        return new MyClass(monitoring);
    }
}

测试:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { SomeSpringConfig.class })
public class SomeSpringConfigTest {

    private String testValue = "testServiceName";

    // this bean is not used
    @Bean
    public MyService monitoringService(){ return new MyService(testValue); }

    // thus this bean cannot be constructed using SomeSpringConfig 
    @Autowired
    public MyClass myClass;

    @Test
    public void theTest(){
        assert(myClass.getMonitoring().getName() == testValue);
    }
}

现在,如果我将@Bean public MyService monitoring(){ ... }替换为@MockBean public MyService monitoring;,它可以工作。我感到很奇怪,我可以轻松地模拟一个bean,而不仅仅是提供它。

=>那么我应该如何为测试添加自己的bean?

编辑:

  • 我认为ThreeDots's answer(创建配置测试类)是一般建议。
  • 但是,Danylo's answer(使用@ContextConfiguration)更适合我的要求,即直接在测试类中添加@Bean。

2 个答案:

答案 0 :(得分:2)

Spring Test需要知道您正在使用什么配置(以及在哪里扫描加载的bean)。为了实现您想要的更多选择,最基本的选择是以下两个:

  1. 在包含您的bean的测试类之外创建配置类

    @Configuration
    public class TestConfig {
    
        @Bean
        public MyService monitoringService() {
            return new MyService();
        }
    }
    

,然后将其添加为测试以作为配置类@SpringBootTest(classes = { SomeSpringConfig.class, TestConfig.class })

  1. 如果只需要在此特定测试中使用此配置,则可以在静态内部类中定义它

    public class SomeSpringConfigTest {
    
        @Configuration
        static class ContextConfiguration {
    
            @Bean
            public MyService monitoringService() {
                return new MyService();
            }
        }
    }
    

这将由Spring Boot测试自动识别并加载

答案 1 :(得分:1)

只需将配置添加为

@ContextHierarchy({
    @ContextConfiguration(classes = SomeSpringConfig.class)
})