基于spring与mockito单元测试Mock对象注入
2024-08-22 14:42:09
转载:http://www.blogjava.net/qileilove/archive/2014/03/07/410713.html
1.关键词
单元测试、spring、mockito
2.概述
单元测试目前已经成为项目中保证代码质量的一种必要方法,对于一些不易构造或者不易获取的对象通过mock的方式进行测试是一种很有效的处理办法。在基于spring的mock测试中,mock对象获取和使用的便利性可以提升单元测试代码的质量。
3.实现原理
Mock对象的注入使用注解和反射,对象注入依赖spring框架支持junit4提供的TestExcutionListeners监听器对象,在监听器中将mock对象注入到单元测试类中。
4.新建对象方式代码
private IAccessServiceaccessService = Mockito.mock(IAccessService.class);
@BeforeClass
public static void beforeClass(){
// 构造并注入Mock对象ICmsProxyService
sceneConfigService.setAccessService(accessService);
}
|
5.监听器方式代码
5.1 实现监听器
继承DependencyInjectionTestExecutionListener类,
实现injectDependencies(TestContexttestContext)方法
public class MockitoDependencyInjectionTestExecutionListener extends
DependencyInjectionTestExecutionListener {
@Override
protected void injectDependencies(TestContext testContext) throws Exception {
super.injectDependencies(testContext);
init(testContext);
}
|
5.2 利用反射注入mock对象
private void init(final TestContext testContext)throws Exception {
Object bean = testContext.getTestInstance();
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if(annotationinstanceof Mock){
//注入Mock实例
MockObject obj = new MockObject();
obj.setType(field.getType());
obj.setObj(Mockito.mock(field.getType()));
field.setAccessible(true);
field.set(bean, obj.getObj());
mockObjectMap.put(field.getName(), obj);
}else if(annotation instanceofAutowired){
injectFields.add(field);
}
}
}
|
AutowireCapableBeanFactory factory =testContext.getApplicationContext().getAutowireCapableBeanFactory();
//Autowired注解注入mock对象
for (Field field :injectFields) {
field.setAccessible(true);
Object object = field.get(bean);
if(objectinstanceof Proxy){
Class targetClass = AopUtils.getTargetClass(object);
if(targetClass ==null)
return;
Field[] targetFields =targetClass.getDeclaredFields();
for(Field targetField : targetFields){
targetField.setAccessible(true);
if(mockObjectMap.get(targetField.getName()) ==null){
continue;
}
targetField.set(getTargetObject(object,mockObjectMap.get(targetField.getName()).getType()),mockObjectMap.get(targetField.getName()).getObj());
}
}else{
Object realObject = factory.getBean(field.getName());
if(null != realObject){
Method[] methods = realObject.getClass().getDeclaredMethods();
for (Method method : methods) {
if(method.getName().equalsIgnoreCase("set" +field.getName())){
method.invoke(realObject, mockObjectMap.get(field.getName()).getObj());
}
}
}
}
}
}
|
5.3 测试类配置
使用@TestExecutionListeners注解,引入监听器,需要mock的对象加上@Mock注解。
@TestExecutionListeners({MockitoDependencyInjectionTestExecutionListener.class})
public class AccessServiceImplTest extends BaseTestCase{
@Autowired
private IAccessServiceaccessService;
@Mock
private IPersonServicepersonService;
@Mock
private IAccessDaoaccessDao;
}
|
6.总结
监听器的方式解放了代码中硬编码注入mock对象,使得代码简洁干净。
最新文章
- poj分类
- 搭建的SSH 框架
- IOS 入门开发教程
- Hibernate,JPA注解@OneToMany_Map
- WM_INITDIALOG与WM_CREATE消息的区别
- vim/Gvim配置
- Android-RecyclerView-Item点击事件设置
- 一步一步学python(四) - 字典
- KafKa介绍(分布式架构)
- python 标准模块 string
- datePicker.js 应用
- 【RL-TCPnet网络教程】第21章 RL-TCPnet之高效的事件触发框架
- EOS行为核心:解析插件chain_plugin
- for循环实例
- java中的锁之AbstractQueuedSynchronizer源码分析(二)
- AndroidKiller报.smali文件丢失问题解决(关闭Android Studio的Instant Run)
- CentOS7.1 Liberty云平台之环境准备(2)
- linux ifconfig -a
- MySql 几个小技巧
- Numpy 的常用操作
热门文章
- STM32F4XX devices vector table for EWARM toolchain.
- java中Keytool的使用总结
- ASIHTTPRequest系列(一):同步和异步请求
- 【GitLab】【GitHub】GitLab和GitHub的双向同步
- Step Detector and Step Counter Sensors on Android
- Fidder发送Get、POST请求
- 基于CentOS的MySQL学习补充三--使用Shell批量创建数据库表
- Linux学习2-在阿里云服务器上部署禅道环境
- 树莓派2B安装Xware迅雷远程下载
- springboot redis多数据源设置