use*_*397 8 java integration-testing spring-test mockito spring-boot
为了避免 Spring 上下文一次又一次地重新加载,我已将带@MockBean注释的注入移至父类,如下所示。
@SpringBootTest
.......
public abstract BaseTest {
@MockBean
protected OneService oneService;
Run Code Online (Sandbox Code Playgroud)
这为需要模拟的测试类提供服务OneService。但是,对于我也想从 扩展的测试BaseTest,但注入真实的OneServicevia@Autowired将不起作用,因为它将继承来自 的模拟注入BaseTest。
public AnotherTest extends BaseTest {
@Autowired
protected OneService oneService;
Run Code Online (Sandbox Code Playgroud)
即使我使用了@Autowired注释,该oneService字段也将是从 继承的模拟实例BaseTest。
有没有办法可以强制注入使用自动装配?
在 Java 中,技术上没有办法覆盖字段。当您在子类中声明具有相同名称的字段时,该字段会隐藏超类中具有相同名称的字段。所以这是一个障碍。
第二个障碍源于这样一个事实:如果超类通过配置模拟,则 Spring Boot 的测试支持无法关闭子类中 bean 的模拟@MockBean。
因此,解决方案是通过在超类中注入真正的 bean 来反转您尝试执行的操作@Autowired,然后在子类中打开对特定 bean 类型的模拟。
@Autowired字段,但不要在子类中重新声明该字段。@MockBean在子类中的类级别声明,指定要模拟哪些类(即 bean 类型)。最后一步会导致继承的字段被子类中的模拟注入。
以下两门课程在实践中演示了这种技术。
@SpringBootTest(classes = BaseTests.Config.class)
class BaseTests {
@Autowired
protected Service service;
@Test
void service() {
assertThat(service.getMessage()).isEqualTo("real");
}
@Configuration
static class Config {
@Bean
Service service() {
return new Service();
}
}
static class Service {
String getMessage() {
return "real";
}
}
}
Run Code Online (Sandbox Code Playgroud)
@MockBean(classes = BaseTests.Service.class)
class MockBeanTests extends BaseTests {
@BeforeEach
void setUpMock() {
when(service.getMessage()).thenReturn("mock");
}
@Test
@Override
void service() {
assertThat(service.getMessage()).isEqualTo("mock");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3065 次 |
| 最近记录: |