如何在@SpringBootTest 中创建可重用的@MockBean 定义?
How to create reusable @MockBean definitions in @SpringBootTest?
我有一个 @SpringBootTest
class,它有一个相当复杂的模拟定义设置,带有模拟的 return 值。
问题:我可以将 @MockBean
设置外部化为自己的 class,这样我就可以在多个 class 中重复使用模拟配置(旁注:我是 不是在这里寻找继承!)。
@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() {
//...
}
}
我想独立加载模拟,而不是全局加载我的所有测试。
我想你的答案就在这里:
像这样创建一个实现这些 MockBeans 的测试配置文件:
@Profile("test")
@Configuration
public class MyMockConfiguration {
@Bean
public SomeService someService() {
SomeService someService = mock(SomeService .class);
// mocked methods and results
return someService ;
}
然后在您的测试中使用带有这些注释的配置文件 class:
@ActiveProfiles("test")
@SpringBootTest
@WebAppConfiguration
@RunWith(SpringRunner.class)
不是您所要求的,但一种可能性是不使用 @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() {
}
}
不幸的是,对于这种方法,实施测试必须在 class 级别上另外列出在扩展中模拟的 beans @MockBean
。
我有一个 @SpringBootTest
class,它有一个相当复杂的模拟定义设置,带有模拟的 return 值。
问题:我可以将 @MockBean
设置外部化为自己的 class,这样我就可以在多个 class 中重复使用模拟配置(旁注:我是 不是在这里寻找继承!)。
@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() {
//...
}
}
我想独立加载模拟,而不是全局加载我的所有测试。
我想你的答案就在这里:
像这样创建一个实现这些 MockBeans 的测试配置文件:
@Profile("test")
@Configuration
public class MyMockConfiguration {
@Bean
public SomeService someService() {
SomeService someService = mock(SomeService .class);
// mocked methods and results
return someService ;
}
然后在您的测试中使用带有这些注释的配置文件 class:
@ActiveProfiles("test")
@SpringBootTest
@WebAppConfiguration
@RunWith(SpringRunner.class)
不是您所要求的,但一种可能性是不使用 @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() {
}
}
不幸的是,对于这种方法,实施测试必须在 class 级别上另外列出在扩展中模拟的 beans @MockBean
。