前提:pom引用
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.0.5.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
</dependency> 背景:
方便后台开发自测接口,去除对象之间的复杂依赖,关注代码逻辑的正确性。
原理:
Mockito就是用Java提供的Dynamic Proxy API来实现的。 以下是简单的小demo:
package com.mock;

import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener; /**
* 所以测试类的基类
*
* @author tom_plus
* @date 2017-01-02-17:20
*/
@ContextConfiguration(locations = {"classpath:applicationContext-test.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners(listeners = {DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class})
public class AbstractServiceIT {
}
package com.mock.demo;

import com.AopTargetUtils;
import com.mock.AbstractServiceIT;
import com.springapp.bean.Teacher;
import com.springapp.service.TeacherService;
import com.springapp.service.TestService;
import com.springapp.utils.SessionContext;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.transaction.annotation.Transactional;
import org.testng.Assert; import java.util.List; import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*; /**
* mock 使用demo
* 一个强大的用于 Java 开发的模拟测试框架
*
* @author tom_plus
* @date 2017-01-02-17:45
*/
public class MockServiceIT extends AbstractServiceIT{
@Mock
SessionContext sessionContext;
@Autowired
private TestService testService;
@Before
public void befTest() {
MockitoAnnotations.initMocks(this);
when(sessionContext.getId()).thenReturn(3);
try {
ReflectionTestUtils.setField(AopTargetUtils.getTarget(testService), "sessionContext", sessionContext);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
@Transactional
public void updateIT() throws Exception {
Teacher teacher = new Teacher();
teacher.settName("樱木花道");
int j = testService.update2(teacher);
System.out.println("result:"+j);
Assert.assertEquals(j,1,"更新成功");
} /**
* 参数匹配器,一旦使用参数匹配器,则方法中必须处处使用参数匹配器
*/
@Test
public void argumentMatcherTest(){
List<String> list = mock(List.class);
when(list.get(anyInt())).thenReturn("hello","world");
String result = list.get(0)+list.get(1);
System.out.println(result);
//verify 方法验证mock 对象的互动次数
verify(list,times(2)).get(anyInt());
verify(list,atLeast(2)).get(anyInt());
Assert.assertEquals("helloworld", result); } /**
* 使用异常处理void 方法
*/
@Test
public void stubbingForVoidMethod() {
List<String> list = mock(List.class);
doThrow(new RuntimeException("you are clear a list!")).when(list).clear();
list.clear();
}
}
package com;

import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils; import java.lang.reflect.Field; /**
* Created by tom_plus on 2017/1/2.
*/
public class AopTargetUtils {
/**
* 获取 目标对象
*
* @param proxy 代理对象
* @throws Exception 默认spring中Service对象是代理对象,不能直接把值设置到属性上,所以我们自己写个小的工具类
*/
public static Object getTarget(Object proxy) throws Exception {
if (!AopUtils.isAopProxy(proxy)) {
return proxy;//不是代理对象
}
//jdk
if (AopUtils.isJdkDynamicProxy(proxy)) {
return getJdkDynamicProxyTargetObject(proxy);
} else { //cglib
return getCglibProxyTargetObject(proxy);
}
} private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");//获得字节码文件中的MethodInterceptor cglib$CALLBACK_0 变量
h.setAccessible(true);
Object dynamicAdvisedInterceptor = h.get(proxy);
Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
return target;
} private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
h.setAccessible(true);
AopProxy aopProxy = (AopProxy) h.get(proxy);
Field advised = aopProxy.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget();
return target;
}
}
												

mockito使用心得的更多相关文章

  1. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  2. NoSql数据库使用半年后在设计上面的一些心得

    NoSql数据库这个概念听闻许久了,也陆续看到很多公司和产品都在使用,优缺点似乎都被分析的清清楚楚.但我心里一直存有一个疑惑,它的出现究竟是为了解决什么问题? 这个疑惑非常大,为此我看了很多分析文章, ...

  3. 我的MYSQL学习心得(二) 数据类型宽度

    我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  4. 我的MYSQL学习心得(三) 查看字段长度

    我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  5. 我的MYSQL学习心得(四) 数据类型

    我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(五) 运 ...

  6. 我的MYSQL学习心得(五) 运算符

    我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  7. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  8. 我的MYSQL学习心得(七) 查询

    我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  9. 我的MYSQL学习心得(八) 插入 更新 删除

    我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得( ...

随机推荐

  1. error 502 in ngin php5-fpm

    unix:/var/run/php5-fpm.sock failed (11: Resource temporarily unavailable) http://stackoverflow.com/q ...

  2. 3.从Node.js操作MongoDB文档

    1.更新文档结构,而非SQL 2.数据库更新运算符 在MongoDB中执行对象的更新时,需要确切的指定需要改变什么字段.需要如何改变.不像SQL语句建立冗长的查询字符串来定义更新. MongoDB中可 ...

  3. 在 IIS 6 和 IIS 7中配置Https,设置WCF同时支持HTTP和HTPPS,以及使用HttpWebRequest和HttpClient调用HttpS

    IIS 7 ,给IIS添加CA证书以支持https IIS 6 架设证书服务器 及 让IIS启用HTTPS服务 WCF IIS 7中配置HTTPS C#利用HttpWebRequest进行post请求 ...

  4. objccn-iOS上的相机捕捉

    在第一台iPhone时,在app里面整合相机的唯一方法就是使用UIImagePickerController.到了iOS4,发布了更灵活的AVFoundation框架. UIImagePickerCo ...

  5. jquery中使用serialize() 序列化表单时 中文乱码问题

    序列化中文时之所以乱码是因为.serialize()调用了encodeURLComponent方法将数据编码了 解决方法就是进行解码 1 原因:.serialize()自动调用了encodeURICo ...

  6. 不会JavaScript能混前端么?能拿到高薪么?

    不会JavaScript能混前端么?能拿到高薪么? 答案是:很难! 为什么这么说呢,理由很简单 1)有很多企业不注重前端开发,当然也就不会给你高薪了,这样的企业以小企业居多. 他们一般对前端开发的认识 ...

  7. (转)Java中使用Jedis操作Redis

    转自http://www.cnblogs.com/liuling/p/2014-4-19-04.html 使用Java操作Redis需要jedis-2.1.0.jar,下载地址:http://file ...

  8. C++静态库与动态库

    C++静态库与动态库 这次分享的宗旨是--让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一 ...

  9. hdu 4717(三分求极值)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4717 思路:三分时间求极小值. #include <iostream> #include ...

  10. STM32解密STM32F103芯片解密STM32F103R6单片机破解多少钱?

    STM32解密STM32F103芯片解密STM32F103R6单片机破解多少钱? STM32F系列单片机芯片解密型号: STM32F100  |  STM32F101  |  STM32F102  | ...