前提: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. MySQL SQL优化

    一.优化数据库的一般步骤: (A) 通过 show status 命令了解各种SQL的执行频率. (B) 定位执行效率较低的SQL语句,方法两种: 事后查询定位:慢查询日志:--log-slow-qu ...

  2. faster r-cnn 在CPU配置下训练自己的数据

    因为没有GPU,所以在CPU下训练自己的数据,中间遇到了各种各样的坑,还好没有放弃,特以此文记录此过程. 1.在CPU下配置faster r-cnn,参考博客:http://blog.csdn.net ...

  3. Proj.4坐标系统创建参数

    Proj.4坐标系统创建参数 本文由乌合之众lym瞎编,欢迎转载blog.cnblogs.net/oloroso 本文原文地址(https://github.com/OSGeo/proj.4/wiki ...

  4. python file

    >>> help(open) Help on built-in function open in module __builtin__: open(...) open(name[, ...

  5. robotframework----模板的使用

    模板只能放在测试用例里,可以测试大数据量,每一行模板的值,都做为用户关键字的输入参数,发下图: 删除特定证书2 的用户关键字如下:

  6. hdu 1300 Pearls

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1300 思路:用dp[i]表示前i种花费最低的情况,则有dp[i]=min(dp[i],dp[j+1]+(( ...

  7. shell不能执行su 后的脚本

    问题:在shell脚本中执行“su – 用户名”后,脚本终止执行,并且切换到su 中指定用户名的交互式界面  现象:我在root中执行一个脚本,但是其中的一些命令或脚本必须用oracle用户来执行., ...

  8. [LeetCode] Best Time to Buy and Sell Stock

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...

  9. MongoDB 安装

    年初换了个硬盘空间更大的vps,这下终于可以装MongoDB了. 1 配置包管理系统(yum) 建立 /etc/yum.repos.d/mongodb-org-3.2.repo文件.内容如下: [mo ...

  10. Excel word “由于本机的限制_该操作已被取消_请与管理员联系”的已生效解决办法 (转 )

    正常解决方法: 1.打开开始菜单,在运行里输入regedit,回车 2.在注册表中,导航到HKEY_CURRENT_USER\Software\Classes\.html 项 3.在默认项上点右键选择 ...