Configure @MockBean component before application start Configure @MockBean component before application start spring spring

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();    }}