Mock 入门,分析stub . mock区别
面向接口编程的测试难的问题
Mock Framework的用处在于我们可以在不实现具体对象的情况下,即在没有某个类的实例的情况下对该对象的行为进行模拟。这一特征对于面向接口的编程非常有用。因为接口的调用者可以在没有接口的具体实现的情况下使用接口,也就是说调用者可以先于接口的实现者行动。也许有人觉得这好像没什么神奇的,即使没有mock我也一样可以使用接口啊,可是我要问:
“在没有接口实现的情况下,你能对调用接口的代码进行测试吗?”
“NullReferenceException”相信很多人都碰到过的吧。由于接口不能定义构造函数,也就无法实例化,导致了调用接口的代码无法运行,当然也就是无法测试。
Mocking能干什么?
从mock 的字面意思就可以了解一二了,它的主要工作是模拟出一个被模拟对象的实例,其中包括模拟对该实例的调用行为(比如访问属性、调用方法之类)、模拟方法或属性访问的返回值、模拟方法和索引的参数传递等等,可以说基本上对于一个对象实例的使用它都可以模拟出来。这样一来,我们就可以好像真的有一个我们需要的实例存在一样,正常地使用它,来完成对调用者代码的开发和测试。
Mock object和stub object一样吗?
当然不一样!写过stub测试程序的人应该知道,stub是真是对象的一个模拟,比如调用者需要一个值,那就让stub输出一个值,如果调用者需要传递一个值给stub,那就在stub中定义一个方法接受该参数。但是这与mock的对象存在本质的区别:
stub虽然说也是模拟,但其本质上对真是对象的一个简单实现,而无论它有多简单它都是一种实现,它是真是存在的,它里面包含了我们定义的操作代码;
反观mock的对象,它根本是不存在的,哪怕一句的简单的不能再简单的代码都不存在。
在理解其区别之前,需要明白一点,他们都是为了同一个目标而出现的,代替依赖部分,让原先的“整合测试”简化为“单元测试”。
mock:使用easymock等包,在程序代码中向被测试代码注入“依赖部分”,通过代码可编程的方式模拟出函数调用返回的结果。
stub:自己写代码代替“依赖部分”。它本身就是“依赖部分”的一个简化实现。
实际上,在能够使用mock的时候,就不应该选择使用stub。但是有时候是必须使用stub的,例如在对遗留代码进行测试时,该部分代码不支持“注入”,那么只能将“替代”这个过程外移,使用stub完成此任务了。
应用场景
就以我现在正在开发这个网站代码为例,来说一下如果在测试的使用Mock object.现在有一个需求,我们需要根据给定的搜索关键字和搜索范围来进行项目的搜索,以MVP的方式实现的话我们定义了一个IView接口:
public interface IView_SearchProject
{
void AttachPresenter(Presenter_SearchProject presenterSearchProject);
SearchRange Range { get;}
string SearchKey { get;}
string UrlBase { get;}
void NavigateTo(string searchUrl);
}
以及一个Presenter:
public class Presenter_SearchProject
{
public Presenter_SearchProject(IView_SearchProject viewSearch)
{
view = viewSearch;
range = view.Range;
prjNav = new ProjectSearchNavigator(view.UrlBase);
query = new SearchQuery();
}
public string GetDesUrl()
{
query.WithDescription = range.WithDescription;
query.WithName = range.WithName;
query.WithKey = range.WithKey;
query.SearchKey = view.SearchKey;
query.Ids = range.Ids;
prjNav.Compile(query);
return prjNav.DestUrl;
}
public void Search()
{
view.NavigateTo(GetDesUrl());
}
private IView_SearchProject view;
private SearchRange range;
private ProjectSearchNavigator prjNav;
private SearchQuery query;
}
ProjectSearchNavigator是一个实现页面跳转的帮助类,负责根据View(这里是一个aspx的页面)传递的搜索关键字SearchKey和querystring构造出搜索页面的地址。SearchQuery类负责解析Request.QueryString集合,因为其中存储的key/value对,需要据此构造出所有查询条件的一个字符串。
Mocking and Testing
Mocking说到底多试为了测试,否则我们没有必要,因为mocking出来的对象并不能作为的真是的代码运行。先把测试的代码贴出来,再进行解释,希望你不要觉得太多了:)
[TestFixture]
public class Presenter_SearchProject_Test
{
[SetUp]
public void SetUp()
{
mockRepository=new MockRepository();//1
mockView = mockRepository.CreateMock<IView_SearchProject>();//2
}
[Test]
public void GetDestUrl()
{
SearchRange range = new SearchRange(true, true, false, string.Empty);
//3
//
Expect.Call(mockView.Range).Return(range) ;
//UrlBase
Expect.Call(mockView.UrlBase).Return("http://localhost");
//SearchKey
Expect.Call(mockView.SearchKey).Return("searchKey");
//4
mockRepository.ReplayAll();
//5
presenter = new Presenter_SearchProject(mockView);
string destUrlReturned = presenter.GetDesUrl();
string destUrlExpected = "http://localhost/ProjectPage/ProjectControl.aspx?"
+"search=searchKey&name=True&key=True&description=False";
//6
Assert.AreEqual(destUrlExpected,destUrlReturned);
}
IView_SearchProject mockView;
MockRepository mockRepository;
Presenter_SearchProject presenter;
[TearDown]
public void TestCleanup()
{
mockRepository.ReplayAll();
mockRepository.VerifyAll();
}
}
1. Rhion.Mock框架中要使用mock的对象都需要从MockRepository 这个对象中产生,它充当一个对象工厂的角色。
2. 这一步就是创建我们使用的mock的对象了,需要以被mock类的类型作为泛型参数。
3. 这一步的3行代码是真正mock的部分,它们分别对应着对mockView的三次调用。
Expect.Call(mockView.Range).Return(range) ;
Expect.Call表示我们希望调用mockVIew的那个方法,也包括属性。
.Return的意思我们打算让这个模拟对象返回什么样的值
综合起来的意思就是:我们希望mockView的调用者在调用MockView的某一个方法(或属性)时返回一个有return标识的值
4. ReplayAll的调用千万不要忘掉,它的意思可以理解为,让之前设定的模拟行为生效,从此之后我们就可以把这个mock的对象当作是一个真是的对象来使用了。我觉得可以把它想像成CLR为我们自动生成了代码一样,为我们生成了一个对被mock对象的实现。
5. 这一步是调用者对mock对象的使用。
6. 测试我们关注的对象的行为是否正常
一个需要注意到地方
presenter = new Presenter_SearchProject(mockView);
像这样的初始化需要注意顺序,必须要等到MockView被真正模拟出来之后,也就是ReplayAll调用之后,因为在presenter 内部需要访问mockView的成员,比如:
range = view.Range;
但是如果你在mock对象调用者初始化的时候没有访问mock对象的成员,那么这样的初始化可以的。因为虽然mock对象的成员还米有mock出来,但是mock对象已经被生成了:
mockView = mockRepository.CreateMock<IView_SearchProject>();
只不过是个空壳:)
转载于:https://www.cnblogs.com/wxc-kingsley/p/8033545.html
Mock 入门,分析stub . mock区别相关推荐
- 快速入门JAVA单元测试——mock
背景 为了确保代码的质量,对编写的代码进行单元测试是非常有必要的. 在JAVA项目中,一般的项目结构比较复杂.依赖众多.在微服务与spring boot大行其道的今天,单纯靠junit来进行单元测试一 ...
- Java注解@Mock和@InjectMocks及@Mock和@Spy之间的区别
Java注解@Mock和@InjectMocks及@Mock和@Spy之间的区别 1.@Mock和@InjectMocks的区别 @Mock为您需要的类创建一个模拟实现. @InjectMocks创建 ...
- Google Mock 入门
Google Mock 入门 原文 概述 什么是Mock? Mock,更确切地说应该是Mock Object.它究竟是什么?它有什么作用?在这里,我也只能先说说我的理解. 比如当我们在单元测试.模块的 ...
- android mock测试资源,Android 单元测试 --Mock 及 Mockito
以前我在 Mock 概念 所谓的 Mock 就是创建一个类的虚假的对象,在测试环境中,用来替换掉真实的对象,主要提供两大功能: 验证这个对象的某些方法的调用情况,调用了多少次,参数是什么等等 指定这个 ...
- bean加载context idea_02-基于IDEA创建SpringBoot项目并进行入门分析
SpringBoot 项目创建 创建Module 基于IDEA创建项目Module,模块名为04-springboot-start,组id和包名为com.cy,如图所示: 填写module信息,如图所 ...
- mysql thread入门分析
MySQL thread入门分析 今天下午和群里的朋友讨论mysql的thread pool,讨论的非常热闹,收获不少,借此自己也总结下thread,以备忘.下面贴上lidan的图片: Mysql支持 ...
- mock模拟接口测试 vue_Easy Mock以及Vue+Mock.js模拟数据
Easy Mock以及Vue+Mock.js模拟数据 一.Mock.js简介 Mock.js是一个可以模拟后端数据,也可以模拟增删改查操作的js库 基础语法规范 数据模板中的每个属性由 3 部分构成: ...
- 面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别
博主选的是老师给出的第一个议题"面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?",首先来讨论一下二者的定义. 结构化方法的基本思想是将待解决的问题看作一个系统从 ...
- Mockito3.8 如何mock静态方法 (如何mock PageHelper)
项目中遇到需要mock PageHelper,因为用到了startPage方法,而此方法是静态方法,如果需要mock静态方法,网上说法比较多的都是需要用Powermock,而这就需要引入新的依赖,这样 ...
- socket入门分析
socket入门分析 一.基于TCP的客户端与服务器端 1.服务器端 初始化socket,绑定特定端口或地址(bind),开始监听(listen),调用accept()d等待客户端请求.接收到客户端请 ...
最新文章
- 全球支付平台paypal社招一面,二面合并面经
- 【WPF】代码触发Button点击事件
- 自动化运维工具Puppet(管理资源)
- DC/DC电源模块介绍
- WinForm中Combobox绑定值问题
- svn update -r m path 代码还原到某个版本(这样之前的log日志也就没了,也就是清空log日志)...
- php hbase thrift,PHP使用Thrift操作Hbase
- Python一行代码给儿子制作九九乘法表
- java模拟数据库压测_Jeecgboot Feign、分布式压测、分布式任务调度
- Tomcat的下载与安装
- linux 2.6.32 sdxc 补丁,在大于32GB或64GB容量的SD卡上使用NOOB安装树莓派
- 主管都在用项目管理Excel表格模板管理项目
- 统计学(第七版)贾俊平课后习题数据
- VBA写一个下拉复选框,以及循环判断,附代码
- 计算机uc,UC浏览器
- SegeX SgxVariantArrayT:VC封装支持多维数组的变体类型(VRIANT 、SafeArray)(附免费免积分源代码)
- ubuntu中trusted.gpg文件有什么作用
- mysql 内存 优化_MySQL核心参数优化(内存优化)
- 当WebRTC Pion示例无音频流的时候,如何添加音频模块并通过浏览器播放?
- MKL FFT简单调试
热门文章
- 51单片机开发入门(1)-单片机简介
- 使用NOPI做Excepl导入导出
- 机器学习-DBSCAN密度聚类
- 安川机器人焊枪切换设定方法_安川机器人工具、用户、安全模式设定方法
- android 9坚果r1,坚果R1、小米MIX2S、一加6对比评测 骁龙845旗舰怎么选?
- 基于51单片机的电容电感电阻RLC测量仪protues仿真
- 个人业务网站php源码,最新个人发卡网源码,PHP运营级个人自动发卡平台完整源码...
- maven 打包命令的使用
- Hadoop面试题及参考答案
- 笔记本win10 1709 安装 v4w的教程