Issue
The question seems extremely simple, but strangely enough I didn't find a solution.
My question is about adding/declaring a bean in a SpringBootTest
, not overriding one, nor mocking one using mockito.
Here is what I got when trying the simplest implementation of my real need (but it doesn't work):
Some service, bean, and config:
@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);
}
}
The test:
@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);
}
}
Now, if I replace the @Bean public MyService monitoring(){ ... }
by @MockBean public MyService monitoring;
, it works. I find it strange that I can easily mock a bean, but not simply provide it.
=> So how should I add a bean of my own for one test?
Edit:
- I think ThreeDots's answer (create a config test class) is the general recommendation.
- However, Danylo's answer (use @ContextConfiguration) fit better to what I asked, i.e. add @Bean directly in the test class.
Solution
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:
Create configuration class outside the test class that includes your bean
@Configuration public class TestConfig { @Bean public MyService monitoringService() { return new MyService(); } }
and then add it to to test as configuration class @SpringBootTest(classes = { SomeSpringConfig.class, TestConfig.class })
or
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(); } } }
this will be automatically recognized and loaded by spring boot test
Answered By - ThreeDots
Answer Checked By - Gilberto Lyons (JavaFixing Admin)