php单元测试进阶(14)- 核心技术 - 动态mock对象
本系列文章主要代码与文字来源于《单元测试的艺术》,原作者:Roy Osherove。译者:金迎。
本系列文章根据php的语法与使用习惯做了改编。所有代码在本机测试通过。如转载请注明出处。
使用手工mock对象的方法可能会遇到问题,包括:
编写mock对象和桩件需要花费时间。
如果类和接口有许多方法,属性和事件,就很难为它编写桩件和mock对象。
难以在其他测试中重用mock类和桩件类。一旦接口有超过两三个方法需要实现,代码维护会很麻烦。
要保存mock对象被多次调用的状态,需要手工实现。
尽管如此,学习手工创建mock对象可以更清楚的学习单元测试的原理,同时,手工编写的mock对象和桩件的代码是更加易读的,并且也确实可以使用。
决定何时用手工创建mock对象,何时用本节介绍的动态mock对象,也是一种艺术。
动态伪对象
动态伪对象是在运行时创建的任何桩件或mock对象,它的创建不需要先硬编码一个类。
动态mock对象的框架
最常用的有两个,一个是PHPUnit_MockObject,这是phpunit自带的默认的mock框架。
另一个是Prophecy,其原本是另一个单元测试框架phpspec的mock类库,但因为很优秀,可以独立使用,可以被内嵌到phpunit当中,并且默认已经有了,无需额外安装。
使用任意一个都可以。本文分别使用一下。
为了学习动态mock,我们需要再仔细读一遍php单元测试进阶(12)- 核心技术 - mock对象。只是我们现在改成动态mock实现。
源代码中,被测类不变,接口也不变。
测试代码中,去除手工mock类文件(少写一个文件!),然后修改测试类如下
测试代码(PHPUnit_MockObject实现)
LogAnalyzerTest.php
<?php
namespace tests\index\controller;
/**
* 测试用的类
*/
class LogAnalyzerTest extends \think\testing\TestCase
{
/**
* @test
* 使用动态mock对象断言,注意:断言代码是写在前面的!!
* 注意,尽量使得测试的方法名称有意义,这非常重要,便于维护测试代码。有规律
*/
public function analyze_TooShortFileName_CallsWebService()
{
$tooShortFileName= 'abc.ext';
// 为 IWebService 接口建立mock对象,只模仿 logError() 方法。
$mockService = $this->getMockBuilder('\app\index\controller\IWebService')
->getMock();
// 现在开始断言:预期该mock对象的 logError() 方法将会被调用一次,
// 并且将以字符串 "Filename too short:{$tooShortFileName}" 为参数。
$mockService->expects($this->once())
->method('logError')
->with($this->equalTo("Filename too short:{$tooShortFileName}"));
// 创建被测类的对象,注入mock对象
$analyzer = new \app\index\controller\LogAnalyzer($mockService);
//调用被测对象,等待断言发生。
$analyzer->analyze($tooShortFileName);
}
}
cmd下测试通过。
测试代码(Prophecy实现)
LogAnalyzerTest.php
<?php
namespace tests\index\controller;
/**
* 测试用的类
*/
class LogAnalyzerTest extends \think\testing\TestCase
{
/**
* @test
* 使用动态mock对象断言,注意:断言代码是写在前面的!!
* 注意,尽量使得测试的方法名称有意义,这非常重要,便于维护测试代码。有规律
*/
public function analyze_TooShortFileName_CallsWebService()
{
$tooShortFileName= 'abc.ext';
// 为 IWebService 接口建立预言(prophecy)。
$mockService = $this->prophesize('\app\index\controller\IWebService');
// 现在开始断言:预期用该mock类生成的对象的 logError() 方法将会被调用一次,
// 并且将以字符串 "Filename too short:{$tooShortFileName}" 为参数。
$mockService->logError("Filename too short:{$tooShortFileName}")->shouldBeCalled();
// 创建被测类的对象,注入mock对象,注意,对象是这里生成,但断言在上面
$analyzer = new \app\index\controller\LogAnalyzer($mockService->reveal());
//调用被测对象,等待断言发生。
$analyzer->analyze($tooShortFileName);
}
}
cmd下测试也通过。其实也能发现用Prophecy做动态mock代码很简洁。
现在可以不手工写mock了!
本系列文章结束。
上一篇:
php单元测试进阶(13)- 核心技术 - mock对象 - 同时使用mock和stub
分享到:
相关推荐
单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络...
用户行为日志生成脚本
mock-service-demo实现一个本地mock服务器, 本地请求指向mock服务器(如配置axios.defaults.baseURL为mock服务器地址), 如果path匹配成功且该path开启了mock配置项则返回mock数据, 否则对请求进行转发(可根据配置转发...
模拟一切使用 mock 进行 python 单元测试的示例模拟 python 2.7: : (这里也有很多很好的例子) 从图书馆的主页: “mock 是一个用于在 Python 中进行测试的库。它允许您用模拟对象替换被测系统的某些部分,并对...
gmall2020-mock-db-2021-11-14.jar
开源项目-Code-Hex-funcy-mock.zip,funcy-mock generates mock file from interface go file
vue-cli-plugin-mock 用于本地模拟数据功能的软件包 简单的写作(Express.js风格) 观看文件更改 自动重装模拟服务器 支持esm / cjs样式模块 安装 yarn add vue-cli-plugin-mock 用vue-cli3安装 vue add vue-cli-...
可以用来Mock JAVA代码中的静态方法
引入你要用到的GoogleMock名称.除宏或其它特别提到的之外所有GoogleMock名称都位于*testing*命名空间之下.建立模拟对象(Mock Obj
在自动测试中,针对dubbo接口进行mock的框架 原理 利用dubbo的扩展点自动包装,通过EasyMockClusterWrapper将原本的rpc请求改写为http请求转发到mock服务器返回我们对应mock结果 使用 1. 添加依赖 mvn clean package...
Laravel开发-laravel-redis-mock 这个Laravel包为您的测试提供了一个redis模拟
Raml-mocker是基于 Raml 的 mock server,Raml 是 RESTfull API 描述语言,同时支持自定义指令。raml-mocker 可以根据 raml 描述文档读取到 API 中的 uri 及 response 中的 example 继而生成 mock server。
Junit单元测试相关jar工具。包含:hamcrest-core-1.3和junit-4.13.1 单元测试 (英语: Unit Testing )又称为 模块测试 ,是针对 程序模块 ( 软件设计 的最小单位)来进行正确性检验的测试工作。. 程序单元是应用...
mock练习
redis-mock是一个专门为Redis设计的单元测试工具,它能在不需要连接真实Redis服务器的情况下,提供redis-mock是一个专门为Redis设计的单元测试工具,它能在不需要连接真实Redis服务器的情况下,提供模拟的Redis数据...
主要介绍了在 Angular-cli 中使用 simple-mock 实现前端开发 API Mock 接口数据模拟功能的方法,需要的朋友可以参考下
SpringBoot 集成的单元测试,代码优化过程中都会使用的技术;MockBean和SpyBean实现单元测试的需求
前端开源库-loglevel-plugin-mockloglevel插件模拟,用于模拟和测试的模板插件
主要介绍了MyBatis-Plus 如何单元测试的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Amazon EC2元数据模拟Amazon EC2 Metadata Mock(AEMM)是一种工具,用于模拟以进行本地测试。目录概括AWS EC2实例元数据是有关您的实例的数据,可用于配置或管理正在运行的实例。实例元数据分为几类,例如主机名,...