Search code examples
javaspringjunitspring-boot-test

How to create reusable @MockBean definitions in @SpringBootTest?


I have a @SpringBootTest class that has a rather complex mock definition setup with mocked return values.

Question: can I externalize @MockBean setups into an own class, so I could reuse the mock configuration in multiple class (sidenote: I'm not looking for inheritance here!).

@SpringBootTest
public class ServiceTest extends DefaultTest {
    @Autowired
    private ServiceController controller;
    
    @MockBean
    private Service1 s1;
    
    @MockBean
    private Service2 s2;
    
    @MockBean
    private Service3 s3;
    
    //assume more complex mock definitions
    @BeforeEach
    public void mock() {
        when(s1.invoke()).thenReturn(result1);
        when(s2.invoke()).thenReturn(result2);
        when(s3.invoke()).thenReturn(result3);
    }
    
    @Test
    public void test() {
        //...
    }
}

I want to load the mocks independently of each other, not globally for all my tests.


Solution

  • Not directly what you are asking for, but one possibility is to not use @MockBean but instead define your reusable mocks as @Primary @Beans in multiple @TestConfigurations that you can selectively @Import in your tests:

    @TestConfiguration
    public class MockService1 {
    
      @Bean
      @Primary
      public Service1 service1Mock() {
        Service1 s1 = Mockito.mock(Service1.class);
        when(s1.invoke()).thenReturn("result1");
        return s1;
      }
    }
    

    There's a nice article about this approach: Building Reusable Mock Modules with Spring Boot.