热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用PHPUnit模拟PDO对象-MockingThePDOObjectusingPHPUnit

ImhavingdifficultymockingthePDOobjectwithPHPUnit.我在使用PHPUnit模拟PDO对象时遇到困难。Theredoesnts

I'm having difficulty mocking the PDO object with PHPUnit.

我在使用PHPUnit模拟PDO对象时遇到困难。

There doesn't seem to be much information on the web about my problem but from what I can gather:

网上似乎没有太多关于我的问题的信息,但是我可以收集的信息:

  1. PDO has 'final' __wakeup and __sleep methods that prevent it from being serialised.
  2. PDO具有“final”__wakeup和__sleep方法,可以防止它被序列化。
  3. PHPunit's mock object implementation serialises the object at some point.
  4. PHPunit的模拟对象实现在某些时候将对象序列化。
  5. The unit tests then fail with a PHP error generated by PDO when this occurs.
  6. 当发生这种情况时,单元测试失败,PDO生成PHP错误。

There is a feature meant to prevent this behavior, by adding the following line to your unit test:

通过在单元测试中添加以下行,有一个旨在防止此行为的功能:

class MyTest extends PHPUnit_Framework_TestCase

{    
    protected $backupGlobals = FALSE;
     // ...

}

Source: http://sebastian-bergmann.de/archives/797-Global-Variables-and-PHPUnit.html

资料来源:http://sebastian-bergmann.de/archives/797-Global-Variables-and-PHPUnit.html

This isnt working for me, my test still produces an error.

这不适合我,我的测试仍然会产生错误。

Full test code:

完整的测试代码:

class MyTest extends PHPUnit_Framework_TestCase
{

    /**
     * @var MyTest
     */
    private $MyTestr;

    protected $backupGlobals = FALSE;

    /**
     * Prepares the environment before running a test.
     */
    protected function setUp()
    {
        parent::setUp();

    }

    /**
     * Cleans up the environment after running a test.
     */
    protected function tearDown()
    {

        parent::tearDown();
    }

    public function __construct()
    {

        $this->backupGlobals = false;
        parent::__construct();

    }


    /**
     * Tests MyTest->__construct()
     */
    public function test__construct()
    {

        $pdoMock = $this->getMock('PDO', array('prepare'), array(), '', false);

        $classToTest = new MyTest($pdoMock);

        // Assert stuff here!


    }

    // More test code.......

Any PHPUnit pro's give me a hand?

任何PHPUnit专业版都能帮到我手中?

Thanks,

谢谢,

Ben

3 个解决方案

#1


47  

$backupGlobals does not help you, because this error comes from elsewhere. PHPUnit 3.5.2 (possibly earlier versions as well) has the following code in PHPUnit/Framework/MockObject/Generator.php

$ backupGlobals对你没有帮助,因为这个错误来自其他地方。 PHPUnit 3.5.2(也可能是早期版本)在PHPUnit / Framework / MockObject / Generator.php中有以下代码

    if ($callOriginalConstructor &&
        !interface_exists($originalClassName, $callAutoload)) {
        if (count($arguments) == 0) {
            $mockObject = new $mock['mockClassName'];
        } else {
            $mockClass  = new ReflectionClass($mock['mockClassName']);
            $mockObject = $mockClass->newInstanceArgs($arguments);
        }
    } else {
        // Use a trick to create a new object of a class
        // without invoking its constructor.
        $mockObject = unserialize(
          sprintf(
            'O:%d:"%s":0:{}',
            strlen($mock['mockClassName']), $mock['mockClassName']
          )
        );
    }

This "trick" with unserialize is used when you ask getMock to not execute the original constructor and it will promptly fail with PDO.

当你要求getMock不执行原始构造函数时,会使用带有反序列化的“技巧”,并且它会立即失败并使用PDO。

So, how do work around it?

那么,如何解决它呢?

One option is to create a test helper like this

一种选择是创建这样的测试助手

class mockPDO extends PDO
{
    public function __construct ()
    {}

}

The goal here is to get rid of the original PDO constructor, which you do not need. Then, change your test code to this:

这里的目标是摆脱你不需要的原始PDO构造函数。然后,将您的测试代码更改为:

$pdoMock = $this->getMock('mockPDO', array('prepare'));

Creating mock like this will execute original constructor, but since it is now harmless thanks to mockPDO test helper, you can continue testing.

像这样创建模拟将执行原始构造函数,但由于mockPDO测试助手现在它是无害的,您可以继续测试。

#2


2  

The best I can think of is to use runkit and redefine the two final methods as protected using runkit_function_redefine.

我能想到的最好的方法是使用runkit并使用runkit_function_redefine重新定义两个最终方法作为protected。

Dont for get to enable the runkit.internal_override setting in php.ini.

不要在php.ini中启用runkit.internal_override设置。

And as ever, as with eval, if runkit seems like the answer, the question is probably wrong :)

和eval一样,如果runkit看起来像答案,问题可能是错误的:)

#3


1  

You are instantiating your test case in your test case?

您是否在测试用例中实例化了测试用例?

$classToTest = new MyTest($pdoMock);

Right now, you are essentially testing your test case. It should be more something like:

现在,您基本上是在测试您的测试用例。它应该更像是:

$classToTest = new My($pdoMock);

推荐阅读
  • php连接mysql显示数据,php连接mysql数据库的算法思想
    本文目录一览:1、怎么用php显示mysql数据表数据 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • IT方面的论坛太多了,有综合,有专业,有行业,在各个论坛里混了几年,体会颇深,以前是论坛哪里人多 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 本文介绍了GregorianCalendar类的基本信息,包括它是Calendar的子类,提供了世界上大多数国家使用的标准日历系统。默认情况下,它对应格里高利日历创立时的日期,但可以通过调用setGregorianChange()方法来更改起始日期。同时,文中还提到了GregorianCalendar类为每个日历字段使用的默认值。 ... [详细]
  • 本文介绍了在Ubuntu下制作deb安装包及离线安装包的方法,通过备份/var/cache/apt/archives文件夹中的安装包,并建立包列表及依赖信息文件,添加本地源,更新源列表,可以在没有网络的情况下更新系统。同时提供了命令示例和资源下载链接。 ... [详细]
  • 本文介绍了如何在Jquery中通过元素的样式值获取元素,并将其赋值给一个变量。提供了5种解决方案供参考。 ... [详细]
  • 本文介绍了使用jQuery实现图片预加载和等比例缩放的方法,同时提供了演示和相关代码。该方法可以重置图片的宽度和高度,并使图片在水平和垂直方向上居中显示。 ... [详细]
  • QuestionThereareatotalofncoursesyouhavetotake,labeledfrom0ton-1.Somecoursesmayhaveprerequi ... [详细]
author-avatar
不爽我就来吐槽_320
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有