Configure @MockBean before launching the application

I have a Spring Boot 1.4.2 application. Some code that is used during startup looks like this:

@Component class SystemTypeDetector{ public enum SystemType{ TYPE_A, TYPE_B, TYPE_C } public SystemType getSystemType(){ return ... } } @Component public class SomeOtherComponent{ @Autowired private SystemTypeDetector systemTypeDetector; @PostConstruct public void startup(){ switch(systemTypeDetector.getSystemType()){ // <-- NPE here in test case TYPE_A: ... case TYPE_B: ... case TYPE_C: ... } } } 

There is a component that determines the type of system. This component is used during startup from other components. Everything works fine in production.

Now I want to add some integration tests using Spring 1.4 @MockBean .

The test looks like this:

 @RunWith(SpringRunner.class) @SpringBootTest(classes = MyWebApplication.class, webEnvironment = RANDOM_PORT) public class IntegrationTestNrOne { @MockBean private SystemTypeDetector systemTypeDetectorMock; @Before public void initMock(){ Mockito.when(systemTypeDetectorMock.getSystemType()).thenReturn(TYPE_C); } @Test public void testNrOne(){ // ... } } 

Mostly bullying works fine. My systemTypeDetectorMock is used, and if I call getSystemType TYPE_C returned.

The problem is that the application does not start. At the moment, the working order of the springs seems to be:

  1. create all Mocks (without configuration, all methods return zero)
  2. launch the application
  3. call @ Before methods (where layouts will be configured)
  4. start test

My problem is that the application starts with an uninitialized layout. So calling getSystemType() returns getSystemType() .

My question is: how can I customize the layouts before running the application?

Edit: If anyone has the same problem, one of the workarounds is to use @MockBean(answer = CALLS_REAL_METHODS) . This calls the real component, and in my case the system starts up. After starting, I can change the behavior layout.

+13
source share
2 answers

The SomeOtherComponent class also requires the @Component annotation.

-1
source

I think this is due to how you automatically link your dependencies. Take a look at this (especially the “Correction # 1: Solve Your Design and Make Your Dependencies Visible” part). That way you can also avoid using @PostConstruct and just use the constructor.

-1
source

Source: https://habr.com/ru/post/1259633/


All Articles