- 浏览: 806408 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
xieye:
jetty插件有好几个版本,1.6,1.7,1.8
我选的是用 ...
tapestry入门(翻译)3 导入项目到eclipse -
xieye:
还有,
注:第2部分时,需要先安装jetty,我自己在安装过程 ...
tapestry入门(翻译)3 导入项目到eclipse -
xieye:
说明一下:实际使用中,导入时我并没有错误。2、我把eclips ...
tapestry入门(翻译)3 导入项目到eclipse -
xieye:
其实还是有一些先决条件的。1是外部环境,2是进步是阶段性的(意 ...
(转载文章)如何愉悦起来:一位精神治疗师的见解 -
mandy_yanzi:
我都已经饿7天了坚持为了我的衣衣
身体健康的问题
php单元测试进阶(13)- 核心技术 - mock对象 - 同时使用mock和stub
本系列文章主要代码与文字来源于《单元测试的艺术》,原作者:Roy Osherove。译者:金迎。
本系列文章根据php的语法与使用习惯做了改编。所有代码在本机测试通过。如转载请注明出处。
假设需求变更,更加复杂一些。
如文件名过短,则web服务记录日志,但万一记录过程中发生异常,需发送一封邮件。
要求测试发送邮件是成功的。
源代码有2个接口,一个被测类。
测试代码有2个伪对象类,一个测试类。
源代码
(1)\t2\application\index\controller下,错误日志接口
IWebService.php
(2)\t2\application\index\controller下,邮件接口
IEmailService.php
(3)被测类,实现万一抛异常,就发邮件这个功能。\t2\application\index\controller下,
LogAnalyzer.php
测试代码
(4)\t2\tests\index\controller下,实现错误日志接口的桩件类
FakeWebService.php
(5)\t2\tests\index\controller下,实现邮件接口的mock类,要断言的
FakeEmailService.php
(6)测试类,主要断言了抛异常时,邮件发送成功。\t2\tests\index\controller下,
LogAnalyzerTest.php
cmd下测试通过。
总结
原作者认为:
一个测试中,应该最多只有一个mock对象,所有其他伪对象都应该是桩件。如有多个mock对象,应分成多个测试,确保每个测试只有一个mock对象。
一个测试只能断言工作单元三种最终结果中的一种。3种结果是,断言返回值,断言对象或系统状态,断言对象交互。目的要明确。如果有多个不同的测试意图,应分成多个测试。
上一篇:php单元测试进阶(12)- 核心技术 - mock对象
下一篇:php单元测试进阶(14)- 核心技术 - 动态mock对象
本系列文章主要代码与文字来源于《单元测试的艺术》,原作者:Roy Osherove。译者:金迎。
本系列文章根据php的语法与使用习惯做了改编。所有代码在本机测试通过。如转载请注明出处。
假设需求变更,更加复杂一些。
如文件名过短,则web服务记录日志,但万一记录过程中发生异常,需发送一封邮件。
要求测试发送邮件是成功的。
源代码有2个接口,一个被测类。
测试代码有2个伪对象类,一个测试类。
源代码
(1)\t2\application\index\controller下,错误日志接口
IWebService.php
<?php namespace app\index\controller; /** * 记录错误日志的接口,供mock对象和真正的对象实现 */ interface IWebService { /** * 记录错误日志 * @param string $message */ public function logError($message); }
(2)\t2\application\index\controller下,邮件接口
IEmailService.php
<?php namespace app\index\controller; /** * 邮件的接口,供mock对象和真正的对象实现 */ interface IEmailService { /** * 发送邮件 * * @param string $to * @param string $subject * @param string $body */ public function sendEMail ($to, $subject, $body); }
(3)被测类,实现万一抛异常,就发邮件这个功能。\t2\application\index\controller下,
LogAnalyzer.php
<?php namespace app\index\controller; /** * 日志分析器类,也是被测类 * * 这是同时使用mock对象和桩件的例子。 */ class LogAnalyzer { /** * @var IWebService */ private $service; /** * @var IEmailService */ private $email; /** * 构造方法注入服务 * @param IWebService $service * @param IEmailService $email */ public function __construct(IWebService $service, IEmailService $email) { $this->service = $service; $this->email = $email; } /** * 分析日志,省略无关功能,检查文件名过短,记录错误日志,可能发生异常。 * @param string $filename */ public function analyze($filename) { if (strlen($filename) < 8 ) { try { $this->service->logError("Filename too short:{$filename}"); } catch ( \Exception $e ) { $this->email->sendEMail("someone@somewhere.com", "can not log", $e->getMessage()); } } // 做一些其他的事情。 // ... ... } }
测试代码
(4)\t2\tests\index\controller下,实现错误日志接口的桩件类
FakeWebService.php
<?php namespace tests\index\controller; /** * 桩件类,要能抛异常,为了测试用 */ class FakeWebService implements \app\index\controller\IWebService { /** * @var \Exception */ public $toThrow; /** * 记录错误日志,但是没有伪实现,只是可能抛异常 * @param string $message */ public function logError($message) { // 字段由外部注入,注入就抛异常 if ($this->toThrow) { throw $this->toThrow; } } }
(5)\t2\tests\index\controller下,实现邮件接口的mock类,要断言的
FakeEmailService.php
<?php namespace tests\index\controller; /** * mock类,要能判断状态。 */ class FakeEmailService implements \app\index\controller\IEmailService { /** * @var string */ public $to; /** * @var string */ public $subject; /** * @var string */ public $body; /** * 发送邮件,伪实现 * * @param string $to * @param string $subject * @param string $body */ public function sendEMail ($to, $subject, $body) { $this->to = $to; $this->subject = $subject; $this->body = $body; } }
(6)测试类,主要断言了抛异常时,邮件发送成功。\t2\tests\index\controller下,
LogAnalyzerTest.php
<?php namespace tests\index\controller; /** * 测试用的类 */ class LogAnalyzerTest extends \think\testing\TestCase { /** * @test * 使用桩件模拟web服务,并在其抛异常后 对mock对象断言 * 注意,尽量使得测试的方法名称有意义,这非常重要,便于维护测试代码。有规律 */ public function analyze_WebServiceThrows_SendEmail() { //创建桩件,并配置使其能抛异常 $stubService = new FakeWebService(); $stubService->toThrow = new \Exception("fake exception"); //创建mock对象,好断言 $mockEmail = new FakeEmailService(); // 创建被测类的对象,注入mock对象和桩件 $analyzer = new \app\index\controller\LogAnalyzer($stubService, $mockEmail); $tooShortFileName= 'abc.ext'; //调用被测对象 $analyzer->analyze($tooShortFileName); // 注意是对mock对象断言!! $this->assertEquals($mockEmail->to, "someone@somewhere.com"); $this->assertEquals($mockEmail->subject, "can not log"); $this->assertEquals($mockEmail->body, "fake exception"); } }
cmd下测试通过。
总结
原作者认为:
一个测试中,应该最多只有一个mock对象,所有其他伪对象都应该是桩件。如有多个mock对象,应分成多个测试,确保每个测试只有一个mock对象。
一个测试只能断言工作单元三种最终结果中的一种。3种结果是,断言返回值,断言对象或系统状态,断言对象交互。目的要明确。如果有多个不同的测试意图,应分成多个测试。
上一篇:php单元测试进阶(12)- 核心技术 - mock对象
下一篇:php单元测试进阶(14)- 核心技术 - 动态mock对象
发表评论
-
召唤神龙 - 安装 centos 8, php 8, mysql 8, laravel 8 的整套 php 运行环境
2020-11-27 16:26 558本文编写时间:2020-11-27 传说集齐龙珠可以召唤神 ... -
centos8 使用阿里镜像快速安装php7.4套件
2020-11-15 00:48 682centos8 使用阿里镜像快速安装php7.4套件 本文只 ... -
centos7 使用阿里镜像快速安装php7.4套件
2020-11-15 00:32 1012本文只考虑centos7 今日 2020-11-16 rem ... -
composer常用命令
2020-11-05 14:46 1055列出当前全局配置 composer config -l -g ... -
期待centos8+php8 + mysql8 + laravel8,8888
2020-10-29 19:24 388期待centos8+php8 + mysql8 目前主要使用 ... -
ubuntu 安装 php7.4以及各类插件
2020-10-24 13:20 904ubuntu 安装 php7.4以及各类插件 安装系统 最近 ... -
宝塔定义站点
2020-02-24 10:41 2宝塔定义站点。 1111111111111111111111 ... -
让php-fpm以root账号运行
2020-02-19 21:41 698一般来说,我们没有这种需求,但是当需要时, 可以让php-fp ... -
将代码部署到coding.net
2020-01-10 14:20 544coding.net 是一个git仓库,有免费有收费。 首先 ... -
php部署工具deployer技巧 - vendor目录创建
2020-01-06 12:06 812deployer是个好东西,可是每次都composer ,其实 ... -
自定义redis多个实例
2020-01-04 01:17 584假如多个项目部署到同一台服务器,有时会被redis的各项目前缀 ... -
推荐使用php的部署工具 deployer
2020-01-03 16:48 815php部署代码可以使用 https://deployer.or ... -
使用composer 类库 cachetool 清除opcache 的缓存
2020-01-03 16:38 887php的生产服务器上,需要把opche打开。 但有时,会被缓 ... -
laravel容器学习体会
2019-12-31 15:11 576根据文档与实测结果 假设我在app下建一个Services目 ... -
phalcon 自定义超强日志类
2019-12-18 10:00 773phalcon自带的日志文件类,有两个麻烦之处。 1、路径不能 ... -
自定义后台的使用
2019-12-18 05:22 364如果自己写后台,保存用户的表单请求值 所有的情况如下: 1 ... -
phalcon 自定义事件使用的多种方式
2019-12-16 20:43 721方法1:官方文档的方式。 这是控制器: public ... -
phalcon对控制器返回值的使用以输出json
2019-12-16 19:17 733在phalcon里,控制器的Action的方法的返回值没啥用。 ... -
phalcon数据库DB使用实例
2019-12-12 17:12 598整理了一下phalcon的db使用,写了个demo。 ... -
php-redis5.0降级成php-redis4.3
2019-08-22 00:01 841最新版本的php的redis插件,版本是5.0 但是可能会有 ...
相关推荐
我们需要用到Stub和Mock来模拟这些外部依赖的对象,从而控制它们 实例 Analyze类会检查filename的长度,如果小于8,我们就会使用一个实现IWebService的类来记录错误. 我们需要给Analyze方法写单元测试
软件包github.com/elliotchance/redismock对于与Redis交互的单元测试应用程序很有用。 它使用了。 与使用真实或伪造的Redis(在下文中有更多介绍)不同, redismock提供了正常且美观的redismock ,以提高控制行为...
Java单元测试对于开发人员质量保证至关重要,尤其当...Mock说白了就是打桩(Stub)或则模拟,当你调用一个不好在测试中创建的对象时,Mock框架为你模拟一个和真实对象类似的替身来完成相应的行为。使用如下方式在Mav
mocha, mocha 是用于 ruby的mock和stub库 mocha 描述用于模拟和stub的ruby 库。完整的。简单的和可以读的语法,完全&部分模拟。内置支持MiniTest和 Test::Unit 。由许多其他测试框架支持。安装 gem使用以下
同时,还涉及mock,stub和框架(如Typemock Isolator和Rhino Mocks)等高级主题,旨在帮助读者逐步掌握高级的测试模式和结构,高效地为遗留代码和甚至根本不可测试的代码编写测试。书中还讨论了测试数据库时需要的工具和...
Lua的测试框架-Mocka 一个模拟类的lua测试框架与项目中的真实类一起运行,具有用于openresty单个测试的nginx嵌入式方法。 预先安装了一套库,您可以指定要安装的库。 Mocka在docker中比在独立环境中运行得更好-您...
-使用特征创建存根和模拟 -定义对模拟的期望 安装 默认情况下在Codeception中启用。 对于PHPUnit,请安装此软件包: composer require codeception/stub --dev 存根 可以使用Codeception\Stub静态调用来构造...
同时,还涉及mock,stub和框架(如Typemock Isolator和Rhino Mocks)等高级主题,旨在帮助读者逐步掌握高级的测试模式和结构,高效地为遗留代码和甚至根本不可测试的代码编写测试。书中还讨论了测试数据库时需要的工具...
开玩笑.fn()和spyOn()spy / stub / mock断言参考要求节点10 纱线1.x或npm设置克隆存储库运行yarn或npm install将安装所有必需的依赖项。npm脚本等效的npm run [removed]也应该起作用yarn test测试使用Jest运行...
正如其名,在单元测试时,CUT(Code Under Test ,被测试代码)可能会依赖其他代码,可以使用JMockit API来mock被依赖的代码,从而进行隔离测试。 JMockit有两套API,mock API用来进行mock测试;mock-up API用来...
它的核心目标是提供一个具有简洁API的测试双重框架,该API能够使用人类可读的领域特定语言(DSL)明确定义所有可能的对象操作和交互。 Mockery被设计为替代PHPUnit的phpunit-mock-objects库的替代品,易于与PHPUnit...
webmock, 在 ruby 中,对HTTP请求的stub和设置期望的库 WebMock 在 ruby 中对HTTP请求进行存储和设置期望的库。特性在低HTTP客户机库级别的Stubbing请求( 在更改HTTP库时不需要更改测试)设置和验证HTTP请求的期望...
Jeek是.NET的一个具体的类/存根/模拟代码生成器,用于单元测试。
在理想情况下,你所做的所有测试都是能应对你实际代码的高级测试。例如,UI测试将模拟实际的用户输入(Klaas 在他的文章中有讨论)等等。实但际上,这并非永远都是个好主意。为每个测试用例都访问一次数据库或者旋转...
这对于集成和验收测试特别有用。 HttpMock在运行时返回罐装响应。用法。 首先,在要测试的应用程序中,使用HttpMock的URL更改要模拟的HTTP服务的URL。 告诉HttpMock监听您提供的端口。 这始终是本地主机,例如: _...
Jest和Mocha的TypeORM模拟单元测试示例 示例如何在Mocha和Jest的模拟单元测试中模拟TypeORM。 这是一个简单的express服务器 用法 测验 运行摩卡单元测试 npm ci npm run test:mocha 运行Jest单元测试 npm run test:...
这使得对依赖于Maps API的组件和其他UI逻辑的测试有些不便,因为您不可避免地不得不在测试中存出相当多的Maps API对象和方法调用,即使是相当琐碎的用法也是如此。 它通常最终会给您的测试增加噪音,并掩盖其意图。...
npm t ( npm run test )将同时运行基于ava和jest的测试套件。 npm start将启动应用程序服务器(默认PORT:3000,可以使用PORT环境变量覆盖) npx jest将仅运行基于jest的测试 npx ava将仅运行基于ava的测试 要求...