【发布时间】:2023-03-26 13:53:01
【问题描述】:
是否有可能以某种方式在同一服务的同一测试类中拥有@MockBean 和@Autowired?
换句话说,我希望@MockBean 服务仅用于一项测试,而对于同一类的其他测试,我需要它作为@Autowired。
【问题讨论】:
-
这些是不同的测试,属于不同的测试类。
标签: java spring junit mockito spring-boot-test
是否有可能以某种方式在同一服务的同一测试类中拥有@MockBean 和@Autowired?
换句话说,我希望@MockBean 服务仅用于一项测试,而对于同一类的其他测试,我需要它作为@Autowired。
【问题讨论】:
标签: java spring junit mockito spring-boot-test
这取决于@MockBean 和@Autowired 之间的区别。
@Autowired只在SpringContext 中查找该类型的bean。这意味着如果您需要“自动装配”它,您将需要创建该 bean
@MockBean完全符合您对名称的期望,它创建了服务的“模拟”,并将其作为 bean 注入。
所以这个
class MyTest {
@MockBean
MyService myService;
}
等价于这个
@Import(MyTest.Config.class)
class MyTest {
@Autowired
MyService myService;
@TestConfiguration
static class Config {
@Bean
MyService myService() {
return Mockito.mock(MyService.class);
}
}
}
因此,如果您需要在其他测试中使用 MyService 类型的不同 bean,则需要在 @TestConfiguration 带注释的类中创建 bean
@Import(MyTest.Config.class)
class MyTest {
@Autowired
MyService myService;
@TestConfiguration
static class Config {
@Bean
MyService myService() {
return new MyServiceImpl();
}
}
}
或者,在一个用@Configuration注解的类中
@Import(MyConfig.class)
class MyTest {
@Autowired
MyService myService;
}
@Configuration
public class MyConfig {
@Bean
MyService myService() {
return new MyServiceImpl();
}
}
【讨论】:
我怀疑这里的邪恶来源是场注入。
Olvier Gierke(现为 Drotbohm)写了一封 blog post 说明为什么场注入是邪恶的。
如果您可以切换到构造函数注入,您可以在测试中模拟服务并将模拟传递给您要测试的类。
我只是想在这里留下这个答案,作为对可能有机会使用构造函数注入的其他人的建议。
【讨论】: