如何在SpringBootTest中添加bean

Juh*_*uh_ 17 java spring unit-testing spring-boot

这个问题看起来非常简单,但奇怪的是我没有找到解决方案。

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

这是我在尝试最简单的实现我的实际需求时得到的结果(但它不起作用):

一些服务、bean 和配置:

@Value // lombok
public class MyService {
    private String name;
}
Run Code Online (Sandbox Code Playgroud)
@Value // lombok
public class MyClass {
    private MyService monitoring;
}
Run Code Online (Sandbox Code Playgroud)
@Configuration
public class SomeSpringConfig {

    @Bean
    public MyClass makeMyClass(MyService monitoring){
        return new MyClass(monitoring);
    }
}
Run Code Online (Sandbox Code Playgroud)

考试:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我替换@Bean public MyService monitoring(){ ... }by @MockBean public MyService monitoring;,它就可以工作了。我觉得很奇怪,我可以轻松地模拟一个 bean,但不能简单地提供它。

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

编辑:

  • 我认为ThreeDots 的答案(创建一个配置测试类)是一般建议。
  • 然而,Danylo的答案(使用@ContextConfiguration)更符合我的要求,即直接在测试类中添加@Bean。

Thr*_*ots 15

Spring Test needs to know what configuration you are using (and hence where to scan for beans that it loads). To achieve what you want you have more options, the most basic ones are these two:

  1. Create configuration class outside the test class that includes your bean

    @Configuration
    public class TestConfig {
    
        @Bean
        public MyService monitoringService() {
            return new MyService();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

and then add it to to test as configuration class @SpringBootTest(classes = { SomeSpringConfig.class, TestConfig.class })

or

  1. If you only need to use this configuration in this particular test, you can define it in static inner class

    public class SomeSpringConfigTest {
    
        @Configuration
        static class ContextConfiguration {
    
            @Bean
            public MyService monitoringService() {
                return new MyService();
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

this will be automatically recognized and loaded by spring boot test