如何在@SpringBootTest 中创建可重用的@MockBean 定义?

问题描述

我有一个 @SpringBoottest 类,它有一个相当复杂的模拟定义设置,带有模拟返回值。

问题:我可以将 @MockBean 设置外部化到一个自己的类中,以便我可以在多个类中重用模拟配置(旁注:我不是在这里寻找继承!)。

@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() {
        //...
    }
}

解决方法

不是您直接要求的,而是一种可能性是不使用 @MockBean 而是将您的可重用模拟定义为多个 @Primary 中的 @Bean @TestConfiguration您可以在测试中选择性地@Import

@TestConfiguration
public class MockService1 {

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

有一篇关于这种方法的好文章:Building Reusable Mock Modules with Spring Boot

,

仅供参考(如果 @TestConfiguration 方法可能因任何原因不适合),它也适用于创建 junit Extension

public class MockService1Extension implements BeforeTestExecutionCallback {
    @Override
    public void beforeTestExecution(ExtensionContext extensionContext) throws Exception {
        ApplicationContext springContext = SpringExtension.getApplicationContext(extensionContext);
        Service1 s1 = springContext.getBean(Service1.class);
        when(s1.invoke()).thenReturn("result1");
    }
}


@ExtendWith(MockService1Extension1.class)
@MockBean({Service1.class})
public class TestImpl {
    @Test
    public void test() {
    }
}

不幸的是,对于这种方法,实现测试必须在类级别额外用 @MockBean 列出扩展内模拟的 bean。

,

我想你的答案就在这里: https://stackoverflow.com/a/50802303/10811865

像这样创建一个实现这些 MockBeans 的测试配置文件:

@Profile("test")
@Configuration
public class MyMockConfiguration {

    @Bean
    public SomeService someService() {
        SomeService someService = mock(SomeService .class);
        // mocked methods and results
        return someService ;
    }

然后在您的测试类中使用带有这些注释的配置文件:

@ActiveProfiles("test")
@SpringBootTest
@WebAppConfiguration
@RunWith(SpringRunner.class)