@MockBean 和@Autowired 同一个服务在一次测试中 class
@MockBean and @Autowired of the same service in one test class
是否有可能以某种方式在同一服务的同一测试中进行 class @MockBean
和 @Autowired
?
换句话说,我只想为一项测试提供 @MockBean
服务,而对于相同 class 的其他测试,我需要它作为 @Autowired
。
这取决于@MockBean
和@Autowired
之间的差异。
@Autowired
仅在 SpringContext
中查找该类型的 bean。这意味着如果需要 'autowire' it
,则需要创建该 bean
@MockBean
完全符合您对名称的期望,它创建了一个 'mock' 服务,并将其作为 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 class
@Import(MyTest.Config.class)
class MyTest {
@Autowired
MyService myService;
@TestConfiguration
static class Config {
@Bean
MyService myService() {
return new MyServiceImpl();
}
}
}
或者,在用 @Configuration
注释的 class 中
@Import(MyConfig.class)
class MyTest {
@Autowired
MyService myService;
}
@Configuration
public class MyConfig {
@Bean
MyService myService() {
return new MyServiceImpl();
}
}
我怀疑这里的罪魁祸首是场注入
Olvier Gierke(现为 Drotbohm)写了一篇 blog post 关于为什么场注入是邪恶的。
如果可以切换到构造函数注入,则可以在测试中模拟服务并将模拟传递给要测试的 class。
我只是想在这里留下这个答案作为对其他可能有机会改用构造函数注入的人的建议。
最好的解决办法是把@MockBean
改成@SpyBean。在该方法中,您可以这样做:
kotlin
@SpyBean
lateinit var serviceMock: Service
@Test
fun smallTest()
`when`(serviceMock.doSomething())
.thenReturn(false)
// your test logic
}
是否有可能以某种方式在同一服务的同一测试中进行 class @MockBean
和 @Autowired
?
换句话说,我只想为一项测试提供 @MockBean
服务,而对于相同 class 的其他测试,我需要它作为 @Autowired
。
这取决于@MockBean
和@Autowired
之间的差异。
@Autowired
仅在 SpringContext
中查找该类型的 bean。这意味着如果需要 'autowire' it
@MockBean
完全符合您对名称的期望,它创建了一个 'mock' 服务,并将其作为 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 class
@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 关于为什么场注入是邪恶的。
如果可以切换到构造函数注入,则可以在测试中模拟服务并将模拟传递给要测试的 class。
我只是想在这里留下这个答案作为对其他可能有机会改用构造函数注入的人的建议。
最好的解决办法是把@MockBean
改成@SpyBean。在该方法中,您可以这样做:
kotlin
@SpyBean
lateinit var serviceMock: Service
@Test
fun smallTest()
`when`(serviceMock.doSomething())
.thenReturn(false)
// your test logic
}