单元测试——使用Mock
一、Mock简介
public class User {private String id;private String pwd;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd;}@Overridepublic String toString() {return "User [id=" + id + ", pwd=" + pwd + "]";}
}
然后创建数据库存储类UserDao
public class UserDao {public void saveUserInfo(User user){//存储数据System.out.println(user);}
}
之后创建自己的测试登陆类Login (这就是一个简单的Mock)
public interface ILogin {public User login();
}
public User login(){User user = new User();ser.setId("1");user.setPwd("123");return user;
}
最近创建测试类进行测试SaveTest
public class SaveTest extends TestCase{private UserDao mUserDao;private ILogin mLogin;@Overrideprotected void setUp() throws Exception {// TODO Auto-generated method stubsuper.setUp();mUserDao = new UserDao();mLogin = new LoginImpl();}public void testSave(){mUserDao.saveUserInfo(mLogin.login());}@Overrideprotected void tearDown() throws Exception {// TODO Auto-generated method stubsuper.tearDown();mUserDao = null;mLogin = null;}
}
根据上面的例子我们可以得出:Mock代表的是模拟某个类(Login类)的行为。这个类是测试你的模块必不可少的类。(必须得有Login才能调用saveUser()存储User)。
二、Mockito的使用
//设置为静态import
import static org.mockito.Mockito.*;public class TestMock extends TestCase {public void testList(){//知识点①List mockList = mock(List.class);//知识点③mockList.add("1");//知识点②verify(mockList,times(2)).add("1");}}
①、使用类的Class类创建测试对象,该类可以是接口、或者具体类。因为并非真正的调用该类的真实方法。
//never():从未被调用过verify(mockList,never()).add("1");//asLeast():至少调用的次数verify(mockList,atLeast(1)).add("1");//atMost():至多调用的次数verify(mockList,atMost(5)).add("1");//times():具体调用的次数verify(mockList,times(3)).add("1");
Stub的使用
public class TestMock extends TestCase {public void testList(){//知识点①LinkedList list = mock(LinkedList.class);//知识点②when(list.get(0)).thenReturn(5);//知识点③int data =(int)list.get(0);System.out.println(data);//输出:5.}
}
①、能够直接获取实现类的Mock对象,不光能获取接口类的Mock对象
public class TestMock extends TestCase {public void testList(){//知识点①LinkedList<String> list = mock(LinkedList.class);//知识点②when(list.get(anyInt())).thenReturn("asd");//知识点③String data =(String)list.get(1);String data2 = (String)list.get(2);System.out.println(data+" "+data2);}
}
3、为连续的调用做测试桩
public class TestMock extends TestCase {public void testList(){LinkedList<String> list = mock(LinkedList.class);//连续调用thenXxx()方法when(list.get(anyInt())).thenReturn("asd").thenThrow(new RuntimeException());String data =(String)list.get(1);System.out.println(data);//返回asdString data2 = (String)list.get(2);//报:RuntimeException()的错}
}
4、制作回调测试桩
public void testList(){List<String> list = mock(List.class);//知识点①when(list.get(anyInt())).thenAnswer(new Answer<String>() {@Overridepublic String answer(InvocationOnMock invocation) throws Throwable {// TODO Auto-generated method stub//获取数据的参数Object [] objs = invocation.getArguments();//获取mock对象本身Object mock = invocation.getMock();return "返回的数据"+objs[0];}});String str = list.get(12);System.out.println(str);}
知识点①、通过调用thenAnswer(),然后调用方法后,会触发Answer的回调,然后通过invocation获取该方法的输入参数。然后进行判定。感觉相当于在Answer对象类,写方法的实现。
public class TestMock extends TestCase {@Mockprivate User mUser;@Mockprivate SaveTest mSaveTest;@Mockprivate ILogin mLogin;@Overrideprotected void setUp() throws Exception {// TODO Auto-generated method stubsuper.setUp();//初始化注解的类,MockitoAnnotations.initMocks(this);//然后就可以了直接使用了,不需要ILogin login = mock(ILogin.class);}@Overrideprotected void tearDown() throws Exception {// TODO Auto-generated method stubsuper.tearDown();}}
使用情形:
<span style="font-size:18px;">//使用情形:测试void方法。
public class TestMock extends TestCase {private User user;public void testMock(){User user = mock(User.class);doThrow(new RuntimeException()).when(user).setId();user.getId();}
}//结果抛出了异常</span>
private User user;
public void testMock(){User user = mock(User.class);doReturn("asd").when(user).setId("zxc");
}//报错了,doReturn不能使用void的方
private User user;public void testMock(){User user = new User();User spy = spy(user);spy.getId();//相当于User user = new User();user.getId();}
作用:变为spy之后,就相当变成了一个Mock,也就是能够调用Mock的所有实现(之前说到的verfity判断、做测试桩)
public void testMock(){List list = new LinkedList();List spy = spy(list);//1、设置测试桩 错误无法使用。when(spy.get(0)).thenReturn("asd");//2、利用doXxx()建立测试桩doReturn("asd").when(list).get(0);//3、测试次数verify(list).get(0);}
但是发现直接使用1、设置测试桩的功能,会报错。因为spy.get(0)调用了真实对象list的方法,但是此时list中是没有值的,所以会调用IndexOutOfBoundsException的异常。
import static org.mockito.Mockito.*;public class SaveTest extends TestCase{private UserDao mUserDao;private ILogin mLogin;@Overrideprotected void setUp() throws Exception {// TODO Auto-generated method stubsuper.setUp();//初始化对象mUserDao = new UserDao();mLogin = mock(ILogin .class);
}public void testSave(){//定义返回的UserUser user = new User();user.setId("number");user.setPwd("123");//设置返回值when(mLogin.login()).thenReturn(user);//实现数据库的存储mUserDao.saveUserInfo(mLogin.login());}@Overrideprotected void tearDown() throws Exception {// TODO Auto-generated method stubsuper.tearDown();mUserDao = null;mLogin = null;}
}
2、那么现在我们需要制作提取数据的功能了。
public class ArticleDao {public void saveArticleInfo(Article article){//存储数据System.out.println(article);}public User getArticleFromDb(int id){//为了简便,仿造数据if (id < 100){return null;}else {Article article= new Article();article.setId(id+"");article.setContent("zxcvcv");return article;}}
}
第二步:
/*** 功能* 获取Article的数据:是从网络还是从本地数据库* 1、首先确定是否从本地获取数据* 2、当本地没数据的时候从网络中获取数据*/
public class ArticleController {private ArticleDao mArticleDao;private IGetArticle mGetArticle;public UserController(IGetArticle getArticle){mGetArticle= getArticle;
}public User getArticle(int id){Article article = null;
if(mArticleDao != null){article = mArticleDao.getUserFromDb(id);}//从网络获取数据if (article== null){article = mGetArticle.getArticle();}return article;}public void setUserDao(ArticleDao articleDao){mArticleDao = articleDao;}
}
第三步:
确定测试类:ArticleController类。能否从数据库中获取到值,如果获取不到值,能否从网络中获取到值....
public class GetUserTest extends TestCase{private IGetArticle mGetArticle;private ArticleDao mArticleDao;private ArticleController mController;@Overrideprotected void setUp() throws Exception {// TODO Auto-generated method stubsuper.setUp();//初始化mock类mGetArticle = mock(IGetArticle.class);//初始化测试类mController = new ArticleController(mLogin);mArticleDao = new ArticleDao();}public void testGetArticle(){//第一步:测试当从UserDao中获取到值的情况,那么结果一定不为nullmController.setArticleDao(mArticleDao);when(mGetArticle.getArticle()).thenReturn(null);Article article = mController.getArticle(120);System.out.println(article);//第二步:测试UserDao返回null的时候,直接从网络中赋值Article myArticle = new Article();myArticle.setId("123");myArticle.setPwd("zxc");when(mGetArticle.getArticle()).thenReturn(myArticle);Article newArticle = mController.getArticle(1);System.out.println(newArticle);}}
单元测试——使用Mock相关推荐
- React 16 + Jest单元测试 之 Mock Functions(Mock Names 和 Custom Matchers)
转载 React 16 + Jest单元测试 之 Mock Functions(Mock Names 和 Custom Matchers) 项目初始化[这里使用之前的项目,节省时间] 项目初始化地址 ...
- Java单元测试(Junit+Mock+代码覆盖率)
单元测试是编写测试代码,用来检测特定的.明确的.细颗粒的功能.单元测试并不一定保证程序功能是正确的,更不保证整体业务是准备的. 单元测试不仅仅用来保证当前代码的正确性,更重要的是用来保证代码修复.改进 ...
- 单元测试与 Mock 方法
Mock 方法是单元测试中常见的一种技术,它的主要作用是模拟一些在应用中不容易构造或者比较复杂的对象,从而把测试与测试边界以外的对象隔离开. 编写自定义的 Mock 对象需要额外的编码工作,同时也可能 ...
- 使用 @MockBean 和 @SpyBean 解决 SpringBoot 单元测试中 Mock 类装配的问题
最近在做某个项目的时候一直使用 @MockBean 来解决单元测试中 Mock 类装配到被测试类的问题.这篇文章主要介绍了 @MockBean 的使用例子以及不使用 @MockBean 而使用@Spy ...
- 单元测试 | 如何Mock IHttpClientFactory
前言 编写单元测试时,常常需要使用Mock框架(例如Moq)生成测试类的依赖接口的"模拟"实现,并验证接口是否按预期使用: _mediatorMock = new Mock< ...
- python单元测试mock_python3的单元测试模块mock与性能测试模块cProfile
我们知道写完了代码需要自己跑一跑进行测试,一个写好的程序如果连测试都没有就上到生产环境是不敢想象的,这么做的人不是太自信就是太无知. 传统测试无非就是自己运行一下程序查看结果,或者前后端服务进行联调, ...
- python单元测试mock_Python单元测试的Mock是怎么回事
单元测试 什么是单元测试, 维基百科上是这么定义的: unit testing is a method by which individual units of source code, sets o ...
- Golang单元测试、Mock测试以及基准测试
之前参加字节跳动青训营而整理的笔记 Golang拥有一套单元测试和性能测试系统,仅需要添加很少的代码就可以快速测试一段需求代码. 一.单元测试 单元测试主要包括:输入.测试单元.输出.期望以及与期望的 ...
- 一文让你掌握单元测试的Mock、Stub和Fake
单元测试中有几个神秘的概念,它们就是Mock,模拟对象:Stub,存根:Fake,伪对象,它们听起来很类似,也很容易混淆,让我们通过这篇文章揭开它们神秘的面纱,探索其幽深的小径. 1.什么是伪对象(F ...
- 单元测试fake mock stub
单元测试fake,mock,stub理解 首先这三个词指的是概念,对于单元测试中各个对象的描述,有助于命名规范.在实际操作中,以测试需求为准. fake指为需要测试单元简单模拟了实际运行环境的,确保正 ...
最新文章
- ROS知识(4)----初级教程之常见问题汇总
- VMware虚拟机安装黑苹果MacOS Mojave系统详细教程
- NotePad++编译代码
- oracle数据库切换教程,oracle 11gR2 物理备用数据库搭建及切换
- 怎么才能学好Java编程写好Java代码?
- 2019温馨的元旦祝福语 2019元旦祝福语大全!收藏备用!
- java 根据类名示例化类_Java LocalDateTime类| minusMinutes()方法与示例
- ActiveRecord 模式杂谈
- php随机访问文章,zblog PHP调用热门文章、随机文章和热评文章代码
- Java线程安全策略
- 完全自定义TabBar(八)
- 让django完成翻译,迁移数据库模型
- 如虎添翼VSPHERE 4/5 环境下 linux/windows 动态扩展磁盘
- 应用随机过程_《常见随机过程》(目录)
- MATLAB(1)---将mat文件转换为csv文件
- Linux spi驱动框架之执行流程-nuc970-att7022
- 花呗的24期利息计算器_花呗利息怎么算 利息计算器算一算花呗分期付款利率
- 网站服务器拥挤如何进去,教你一招:有效解决网络拥挤的办法!
- java.sql.time 格式_java.sql.Date,java.sql.Time和java.sql.Timestamp什么区别
- 万级送风天花工作原理以及操作方法