【发布时间】:2014-11-18 21:53:14
【问题描述】:
我想使用 spring-test 配置内部类 (@Configuration) 配置组件测试。测试的组件有一些我想为测试模拟的服务。这些服务是类(不使用接口),并在其中包含 spring 注释 (@Autowired)。 Mockito 可以轻松地模拟它们,但是,我发现无法禁用弹簧自动装配。
我如何轻松复制的示例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SomeTest.Beans.class)
public class SomeTest {
// configured in component-config.xml, using ThirdPartyService
@Autowired
private TestedBean entryPoint;
@Test
public void test() {
}
@Configuration
@ImportResource("/spring/component-config.xml")
static class Beans {
@Bean
ThirdPartyService createThirdPartyService() {
return mock(ThirdPartyService.class);
}
}
}
public class ThirdPartyService {
@Autowired
Foo bar;
}
public class TestedBean {
@Autowired
private ThirdPartyService service;
}
在本例中,“TestBean”代表要模拟的服务。我不希望在春天注入“酒吧”! @Bean(autowire = NO) 没有帮助(事实上,这是默认值)。
(请把我从“使用接口!”cmets 中拯救出来——模拟的服务可以是我无法做任何事情的第 3 方。)
更新
Springockito 部分解决了这个问题,只要您不需要配置其他任何东西(因此您不能将配置类与 Springockito 一起使用 - 它不支持它),但只能使用模拟。 还在寻找纯弹簧解决方案,如果有的话……
【问题讨论】:
-
您能否详细说明您要测试的内容?最佳解决方案很大程度上取决于您实际想要测试的内容
-
我不确定你是否必须模拟其他模拟的依赖关系。至少,它打破了我的单元测试世界。
-
@geo 我稍微更新了这个例子。我想测试在主范围内配置的 bean,但必须在测试范围内部分模拟上下文才能使其工作。问题是模拟类具有 Autowired 注释,并且无法关闭注入它。
-
@walv 这就是重点..我不想依赖模拟,但春天有点强迫我。
-
@vuk 这是见仁见智的问题。但是我个人认为在字段上使用
@Autowired绝不是一个好主意。它会像您指定的情况一样杀死重用。所以在这种情况下,这不是测试适应的问题,而是使组件易于重用的问题,无论上下文如何。解决您的问题的另一种方法是注册一个自定义AutowiredAnnotationBeanPostProcessor,它将忽略您想要的字段。您可以将其与 Spring 配置文件结合使用,以便仅将其用于测试。如果您想进一步探索,我可以将其添加为包含更多信息的答案
标签: java spring junit mockito spring-test