Configure @MockBean component before application start
In this case you need to configure mocks in a way we used to do it before @MockBean
was introduced - by specifying manually a @Primary
bean that will replace the original one in the context.
@SpringBootTestclass DemoApplicationTests { @TestConfiguration public static class TestConfig { @Bean @Primary public SystemTypeDetector mockSystemTypeDetector() { SystemTypeDetector std = mock(SystemTypeDetector.class); when(std.getSystemType()).thenReturn(TYPE_C); return std; } } @Autowired private SystemTypeDetector systemTypeDetector; @Test void contextLoads() { assertThat(systemTypeDetector.getSystemType()).isEqualTo(TYPE_C); }}
Since @TestConfiguration
class is a static inner class it will be picked automatically only by this test. Complete mock behaviour that you would put into @Before
has to be moved to method that initialises a bean.
You can use the following trick:
@Configurationpublic class Config { @Bean public BeanA beanA() { return new BeanA(); } @Bean public BeanB beanB() { return new BeanB(beanA()); }}@RunWith(SpringRunner.class)@ContextConfiguration(classes = {TestConfig.class, Config.class})public class ConfigTest { @Configuration static class TestConfig { @MockBean BeanA beanA; @PostConstruct void setUp() { when(beanA.someMethod()).thenReturn(...); } }}
At least it's working for spring-boot-2.1.9.RELEASE
I was able to fix it like this
@RunWith(SpringRunner.class)@SpringBootTest(classes = MyWebApplication.class, webEnvironment = RANDOM_PORT)public class IntegrationTestNrOne { // this inner class must be static! @TestConfiguration public static class EarlyConfiguration { @MockBean private SystemTypeDetector systemTypeDetectorMock; @PostConstruct public void initMock(){ Mockito.when(systemTypeDetectorMock.getSystemType()).thenReturn(TYPE_C); } } // here we can inject the bean created by EarlyConfiguration @Autowired private SystemTypeDetector systemTypeDetectorMock; @Autowired private SomeOtherComponent someOtherComponent; @Test public void testNrOne(){ someOtherComponent.doStuff(); }}