Spring 使用ServiceLocatoryFactoryBean自动连线对类进行单元测试
我有一个作为ServiceLocatoryFactoryBean的一部分注册的接口。此接口的主要目的是充当工厂 我已经在不同的类中“自动连接”了这个接口,现在我想用Mockito测试它 问题是Mockito不支持接口。如何在我正在测试的类中注入此接口的模拟Spring 使用ServiceLocatoryFactoryBean自动连线对类进行单元测试,spring,junit,mockito,springmockito,Spring,Junit,Mockito,Springmockito,我有一个作为ServiceLocatoryFactoryBean的一部分注册的接口。此接口的主要目的是充当工厂 我已经在不同的类中“自动连接”了这个接口,现在我想用Mockito测试它 问题是Mockito不支持接口。如何在我正在测试的类中注入此接口的模拟 我看到的唯一替代方法是使用SpringJunitRunner运行测试,并提供具有bean配置的应用程序上下文。但这太冗长了 我想你想监视Spring为你的接口生成的实现?!这几乎不可能用你目前所拥有的来实现。。。但是,以下至少有以下备选方案
我看到的唯一替代方法是使用SpringJunitRunner运行测试,并提供具有bean配置的应用程序上下文。但这太冗长了 我想你想监视Spring为你的接口生成的实现?!这几乎不可能用你目前所拥有的来实现。。。但是,以下至少有以下备选方案 假设我们有以下设置:
公共接口MyService{
字符串doIt();
}
@组件
公共静态类ServiceConsumer{
@自动连线
私人MyService服务;
公共字符串execute(){
return service.doIt();
}
}
0)稍后编辑:同时,我发现可以监视甚至用模拟替换自动连接的字段,而且使用起来也相当简单
@RunWith(SpringJUnit4ClassRunner.class)
@组件扫描
@ContextConfiguration(loader=SpringockitoAnnotatedContextLoader.class,class={SpringockitoConsumerTest.class})
公共类SpringockitoConsumerTest{
@幽灵间谍(beanName=“myService”)
@自动连线
私人MyService mockService;
@自动连线
私人服务消费者;
@试验
public void shouldConsumerService(){
assertEquals(“allDone”,consumer.execute());
验证(mockService).doIt();
}
}
如果Springockito注释是不可能的,请参阅下面的2个原始建议
1)您只需创建接口的模拟,并将其自动注入bean中。这是最简单的解决方案(我在撰写本文时可以想到),但它不能确保消费者不会忘记@Autowired
注释(也许可以添加一个专用测试):
公共类AutoInjectMocksConsumerTest{
@嘲弄
私有MyService-serviceMock;
@注射模拟
私有服务消费者=新服务消费者();
@以前
公共void initMocks(){
initMocks(this);
when(serviceMock.doIt())。然后返回(“全部完成”);
}
@试验
public void shouldConsumerService(){
assertEquals(“allDone”,consumer.execute());
验证(serviceMock.doIt();
}
}
2)或者,正如您所说,您可以使用SpringJunitRunner
运行它,尽可能少地定义和实例化必要的Spring上下文,同时提供您自己的服务模拟。尽管人们可能会抱怨此解决方案不够干净,但我发现它足够优雅,它还验证了消费者实现中没有忘记@Autowired
注释
@RunWith(SpringJUnit4ClassRunner.class)
@配置
@组件扫描
@ContextConfiguration(类={SpringAutowiringConsumerTest.class})
公共类SpringAutowiringConsumerTest{
@自动连线
私人MyService mockService;
@自动连线
私人服务消费者;
@试验
public void shouldConsumerService(){
assertEquals(“allDone”,consumer.execute());
验证(mockService).doIt();
}
@豆子
公共MyService mockService(){
MyService serviceMock=mock(MyService.class);
when(serviceMock.doIt())。然后返回(“全部完成”);
返回serviceMock;
}
}
您所说的“Mockito不支持接口”是什么意思?它完全做到了:)这有什么问题?例如:MyInterface-MyInterface=Mockito.mock(MyInterface.class)代码>然后,您可以在创建要测试的类时设置此选项。上面问题中的一个小更正是,我试图@spy该接口,而不是模拟它。问题是我没有该接口的类的具体实现。如果您查看我在上面发布的ServiceLocatorFactoryBean链接,文档中提到您只需创建一个接口,就可以了,spring提供了该接口的运行时实现。但是,spy不能使用接口。这来自Mockito.spy文档“但Mockito无法实例化内部类、本地类、抽象类和接口。”非常感谢您在@Morfic上的评论。非常有用。