Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace a @MockBean?

Is it possible to replace an inherited @MockBean with the real @Bean?

I have an abstract class that defines many configurations and a setup for all ITests. Only for one single test I want to make use of the real bean, and not used the mocked one. But still inherit the rest of the configuration.

@Service
public class WrapperService {
       @Autowired
       private SomeService some;
}

@RunWith(SpringRunner.class)
@SpringBootTest(...)
public abstract class AbstractITest {
    //many more complex configurations

    @MockBean
    private SomeService service;
}

public class WrapperServiceITest extends AbstractITest {
    //usage of SomeService should not be mocked
    //when calling WrapperService

    //using spy did not work, as suggested in the comments
    @SpyBean
    private SomeService service;;
}
like image 218
membersound Avatar asked Aug 06 '18 10:08

membersound


People also ask

What is the difference between @mock and @MockBean?

@Mock is used when the application context is not up and you need to Mock a service/Bean. @MockBean is used when the application context(in terms of testing) is up and you need to mock a service/Bean.

What is MockBean annotation?

Spring Boot's @MockBean AnnotationThe mock will replace any existing bean of the same type in the application context. If no bean of the same type is defined, a new one will be added. This annotation is useful in integration tests where a particular bean, like an external service, needs to be mocked.

Does @springboottest include @MockBean?

Spring Boot provides @MockBean annotation that can be used to define a Mockito mock for a bean inside our ApplicationContext , that means the mock declared in test class (by using @MockBean) will be injected as a bean within the application.

What is a SpyBean?

The @SpyBean is a Spring Boot test annotation that is used to add Mockito spies to ApplicationContext . 2. Spies can be applied by type or bean name. 3. All existing beans of the same type defined in the context will be wrapped with spy and if no existing bean then new one will be added to context.


1 Answers

Found a way using a test @Configuration conditional on a property, and overriding that property in the impl with @TestPropertySource:

public abstrac class AbstractITest {    
    @TestConfiguration //important, do not use @Configuration!
    @ConditionalOnProperty(value = "someservice.mock", matchIfMissing = true)
    public static class SomeServiceMockConfig {
        @MockBean
        private SomeService some;
    }
}


@TestPropertySource(properties = "someservice.mock=false")
public class WrapperServiceITest extends AbstractITest {
    //SomeService will not be mocked
}
like image 155
membersound Avatar answered Sep 24 '22 03:09

membersound