框架Mockito
一、什么是mock测试,什么是mock对象?
先来看看下面这个示例:

从上图可以看出如果我们要对A进行测试,那么就要先把整个依赖树构建出来,也就是BCDE的实例。
一种替代方案就是使用mocks

从图中可以清晰的看出
mock对象就是在调试期间用来作为真实对象的替代品。
mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。
二、什么是Mockito
Mockito是一个针对Java的mocking框架。它与EasyMock和jMock很相似,但是通过在执行后校验什么已经被调用,它消除了对期望行为(expectations)的需要。其它的mocking库需要你在执行前记录期望行为(expectations),而这导致了丑陋的初始化代码。
官方网站:http://code.google.com/p/mockito/
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
</dependency>
java类里要引入
三、Stub和Mock
相同点:Stub和Mock对象都是用来模拟外部依赖,使我们能控制。
不同点:而stub完全是模拟一个外部依赖,用来提供测试时所需要的测试数据。而mock对象用来判断测试是否能通过,也就是用来验证测试中依赖对象间的交互能否达到预期。在mocking框架中mock对象可以同时作为stub和mock对象使用,两者并没有严格区别。 更多信息:http://martinfowler.com/articles/mocksArentStubs.html
四、mockito入门实例
1.1、模拟对象
// 模拟LinkedList 的对象
LinkedList mockedList = Mockito.mock(LinkedList.class);
// 此时调用get方法,是会返回null,因为还没有对方法调用的返回值做模拟
System.out.println(mockedList.get(999));
1.2、模拟方法调用的返回值
// 模拟获取第一个元素时,返回字符串first
Mockito.when(mockedList.get(0)).thenReturn("first");
// 此时打印输出first
System.out.println(mockedList.get(0));
1.3、模拟方法调用抛出异常
Mockito.doThrow(new RuntimeException()).when(mockedList).clear();
1.4、模拟方法调用的参数匹配
Matchers类内加你有很多参数匹配器 anyInt、anyString、anyMap.....Mockito类继承于Matchers,Stubbing时使用内建参数匹配器。例如anyint()如下:
1.5、验证方法调用次数
示例二(web中的3层中的针对某一层的测试):
以前没接触过Mock类型的框架,比如说要测试action层,我总是从action层调用service再调用dao访问数据库,这种方式从原则上来说是无疑是非常正确的,在没用mock框架之前我就隐隐约约的感觉到了这种方式有个不足的地方,那就是速度问题,测试action层的时候需要访问下面两层,如果我们下面两层已经经过单元测试证明是ok的,那么如果测试action层的时候再调用下面两层就等于是做了重复的动作,逻辑上没问题,只是有点重复,并且速度很慢,毕竟项目做到靠后期的时候文单元测试非常多,maven在自动测试的时候速度会非常慢。
而mock框架原理就是模拟对象,方法调用,异常抛出等动作,文档上面介绍他主要解决的问题是项目中有时候依赖不存在的情况下来模拟一来,然而我却是因为速度问题用这个框架,造成这个现象的原因是因为我的项目原因,因为项目不大,逻辑不是很复杂,我在开发的时候往往能从dao、service到action一气呵成来做,不存在模拟依赖的问题,而只是想要解决测试的时候性能问题。当然我的情况是个例,不过我认为mock框架的作用就是这两个:
1.模拟依赖
2.解决单元测试的重复测试来提升性能。
Mockito的使用:我们以User类来测试。
1.把包加入到project中来:此处版本为1.9.5。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
2.POJO
public class User {
private String id;
private String name;
private Integer age;
// getter,setter
}
3.UserDao,此处的接口是没有实现的,我们就是为了能模拟接口的实现,感觉上就像Spring为此接口注入了实现一样
public interface UserDao {
User insertUser(User user);
void deleteUser(User user);
}
4.UserService
public interface UserService {
User insertUser(User user);
void deleteUser(User user);
}
5.UserServiceImpl

public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl() {}
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
public User insertUser(User user) {
return userDao.insertUser(user);
}
public void deleteUser(User user) {
userDao.deleteUser(user);
}
}

6.测试
package com.dxz.mockito; import java.util.LinkedList; import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito; public class UserServiceTest { private UserService userService; @Test
public void insertUserTest() {
// pojo对象
User user = new User();
user.setId("123");
user.setName("Jay");
user.setAge(100); // mock一个userDao对象,本来是不存在的
UserDao userDao = Mockito.mock(UserDao.class);
Mockito.when(userDao.insertUser(user)).thenReturn(user);
User u = userDao.insertUser(user);
System.out.println(u); // 这里模拟Spring给userService注入userDao
userService = new UserServiceImpl(userDao);
User us = userService.insertUser(user);
System.out.println(us); // 测试结果ok
Assert.assertEquals(us, user); // 在开发中有接口UserDao但是没有实现,因此UserService里面的userDao属性也是没有实现的,
// 模拟Spring给UserService里面的userDao注入一个实现,实际上没有注入,而仅仅是mock了一个userDao
// 在userService调用insertUser(User user)方法的时候就能模拟实现
// 当然这里仅仅mock了方法调用返回,还有mock异常,验证调用次数等
// 从整个来讲,这个框架是十分简单易用功能强大的,这里的简单是指使用简单,框架本身是相当复杂的
}
}
web编程中,代码一般分3层,controller层,service层,DAO层,分别的测试方法为:
DAO层:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = com.dxz.common.dao.MySqlAutoConfiguration.class)
@EnableAutoConfiguration
@MapperScan("com.dxz.risk.mapper")
//@ActiveProfiles("sonar")
@Ignore
public class RiskBacklistMapperTest { private static final Logger LOG = LoggerFactory.getLogger(RiskBacklistMapperTest.class); @Autowired
RiskBacklistMapper riskBacklistMapper; RiskBacklist riskBacklist; @Before
public void setUp() throws Exception {
riskBacklist = new RiskBacklist();
riskBacklist.setMemberId("123");
riskBacklist.setMsisdn("13530030000");
riskBacklist.setUsername("duanxz");
riskBacklist.setState(1);
riskBacklist.setPlateform(new Byte("1"));
} @Test
public void testInsert() {
riskBacklistMapper.insert(riskBacklist);
}
// 事务自动回滚,默认是true。可以不写
@Test
@Transactional
@Rollback(true)
public void testUpdateByPayId() {
RiskBacklist riskBacklistTemp = riskBacklistMapper.queryByMsisdn("13530030927");
LOG.info("query from db={}", riskBacklist);
if(riskBacklistTemp != null) {
riskBacklistTemp.setUsername("duanxz2");
int result = riskBacklistMapper.updateByPrimaryKey(riskBacklistTemp);
LOG.info("result={}", result);
assertEquals(1, 1);
} else {
LOG.info("result={}", "");
} }
}
service层:
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("sonar")
@Ignore
public class BacklistCheckServiceImplMockTest { private static final Logger LOG = LoggerFactory.getLogger(BacklistCheckServiceImplMockTest.class); /**
* 被注入mock对象的类,即被测试的类
*/
@Autowired
@InjectMocks
private BacklistCheckService backlistCheckService; BacklistReqDTO reqDTO; /**
* 需要mock的DAO
*/
@Mock
private RiskBacklistMapper riskBacklistMapper; @Before
public void setUp() throws Exception {
reqDTO = new BacklistReqDTO();
reqDTO.setMsisdn("13530030000"); RiskBacklist riskBacklist = new RiskBacklist();
riskBacklist.setMsisdn("13530030000");
riskBacklist.setPlateform(1);
riskBacklist.setState(2);
riskBacklist.setUsername("duanxz");
Mockito.when(riskBacklistMapper.queryByMsisdn("13530030000")).thenReturn(riskBacklist);
} @Test
public void isBacklist() {
boolean result = backlistCheckService.isBacklist(reqDTO);
LOG.info("result={}", result); //断言对比业务结果
assertEquals(true, result);
} }
controller层:
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("sonar")
@Ignore
public class BacklistCheckControllerMockTest { /**
* 模拟MVC对象,通过MockMvcBuilders.webAppContextSetup(this.wac).build()初始化。
*/
private MockMvc mockMvc; /**
* 被注入mock对象的类,即被测试的类
*/
@InjectMocks
private BacklistCheckController backlistCheckController; /**
* 需要mock的DAO
*/
@Mock
private BacklistCheckService backlistCheckService; private BacklistReqDTO reqDTO; @Before
public void setUp() throws Exception {
reqDTO = new BacklistReqDTO();
reqDTO.setMsisdn("13530030927");
mockMvc = MockMvcBuilders.standaloneSetup(backlistCheckController).build(); Mockito.when(backlistCheckService.isBacklist(reqDTO)).thenReturn(true);
} @Test
public void testIsBacklist() throws Exception {
MvcResult result = mockMvc
.perform(post("/isBacklist").contentType(MediaType.APPLICATION_JSON).content(GsonUtils.toJson(reqDTO)))
.andExpect(status().isOk())// 模拟向testRest发送get请求
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))// 预期返回值的媒体类型text/plain;charset=UTF-8
.andReturn();// 返回执行请求的结果 // 打印结果,给研发看的
System.out.println(result.getResponse().getContentAsString()); RespResult<Boolean> resultObj = GsonUtils.fromJson2Object(result.getResponse().getContentAsString(),
RespResult.class); //断言对比返回码
assertEquals(RespSystemCode.SUCCESS.getCode(), resultObj.getRespCode());
//断言对比业务结果
assertTrue(resultObj.getData());
} }
框架Mockito的更多相关文章
- mock测试框架Mockito
无论是敏捷开发.持续交付,还是测试驱动开发(TDD)都把单元测试作为实现的基石.随着这些先进的编程开发模式日益深入人心,单元测试如今显得越来越重要了.在敏捷开发.持续交付中要求单元测试一定要快(不能访 ...
- 测试驱动开发神器框架Mockito
作为菜鸟的我,以前没接触过Mock类型的框架,比如说要测试action层,我总是从action层调用service再调用dao访问数据库,这种方式从原则上来说是无疑是非常正确的,在没用mock框架之前 ...
- 测试框架Mockito使用笔记
Mockito,测试框架,语法简单,功能强大! 静态.私有.构造等方法测试需要配合PowerMock,PowerMock有Mockito和EasyMock两个版本,语法相同,本文只介绍Mockito. ...
- Java测试框架Mockito源码分析
1.Mockito简介 测试驱动的开发(Test Driven Design, TDD)要求我们先写单元测试,再写实现代码.在写单元测试的过程中,一个很普遍的问题是,要测试的类会有很多依赖,这些依赖的 ...
- Mock测试框架(Mockito为例)
在做单元测试的时候,有的时候用到的一些类,我们构造起来不是那么容易,比如HttpRequest,或者说某个Service依赖到了某个Dao,想构造service还得先构造dao,这些外部对象构造起来比 ...
- Mockito:一个强大的用于Java开发的模拟测试框架
https://blog.csdn.net/zhoudaxia/article/details/33056093 介绍 本文将介绍模拟测试框架Mockito的一些基础概念, 介绍该框架的优点,讲解应用 ...
- [转载]5分钟了解Mockito
原文链接: http://liuzhijun.iteye.com/blog/1512780/ 5分钟了解Mockito 博客分类: Open SourceJava 一.什么是mock测试,什么是moc ...
- 用Mockito测试SpringMVC+Hibernate
用Mockito测试SpringMVC+Hibernate 译自:Spring 4 MVC+Hibernate 4+MySQL+Maven integration + Testing example ...
- 15类Android通用流行框架
15类Android通用流行框架 Android流行框架 缓存 DiskLruCache Java实现基于LRU的磁盘缓存 图片加载 Android Universal Image Loader 一个 ...
随机推荐
- CCNA 课程 七
WAN(Wide Area Network)广域网 运行在OSI模型的数据链路层.物理层. 数据链路层的协议主要有: HDLC (High-Level Data Link Control 高级数据链 ...
- 修改redhat默认显示语言为中文
[delmore@localhost Desktop]$ su //切换到最高权限 Password: ...
- java转义符的一些用法
那么这里在列上一些转义字符 \\ 反斜杠 \t 间隔 ('\u0009')\n 换行 ('\u000A')\r 回车 ('\u000D')\d 数字 等价于 [0-9]\D 非数字 等价于 [^0-9 ...
- thinkphp URL 模式
兼容ThinkPHP三种url模式的nginx rewrite location / { root /var/www; index index.html index.htm index.php; if ...
- Luogu-3346 [ZJOI2015]诸神眷顾的幻想乡
\(trie\)树建广义后缀自动机: \(dfs\)遍历\(trie\)树,将树上的一个节点插入\(sam\)时,将他的\(fa\)在\(sam\)上所在的节点作为\(last\) #include& ...
- sqoop学习2(数据导入与导出)
最近学习了下这个导数据的工具,但是在export命令这里卡住了,暂时排不了错误.先记录学习的这一点吧 sqoop是什么 sqoop(sql-on-hadoop):是用来实现结构型数据(如关系型数据库) ...
- JavaWeb -- Jsp 和 JavaBean
JSP技术提供了三个关于JavaBean组件的动作元素,即JSP标签,它们分别为: <jsp:useBean>标签:用于在JSP页面中查找或实例化一个JavaBean组件. <jsp ...
- centos6.5 安装JDK
今天在自己的centos机子上安装jdk,发现以前的教程都比较旧了,很多东西都过时了.今天把自己安装的感受写一下. 判断是否安装 首先,我们得判断机子上是不是安装了jdk,好多人推荐使用java -v ...
- hdoj1012--u Calculate e
Problem Description A simple mathematical formula for e is where n is allowed to go to infinity. Thi ...
- JNI_Z
1. ZC: 用到 VC6 ... http://blog.csdn.net/jiangwei0910410003/article/details/17465085 http://blog.csdn. ...