作者:不爽我就来吐槽_320 | 来源:互联网 | 2023-05-19 06:34
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:
网上似乎没有太多关于我的问题的信息,但是我可以收集的信息:
- PDO has 'final' __wakeup and __sleep methods that prevent it from being serialised.
- PDO具有“final”__wakeup和__sleep方法,可以防止它被序列化。
- PHPunit's mock object implementation serialises the object at some point.
- PHPunit的模拟对象实现在某些时候将对象序列化。
- The unit tests then fail with a PHP error generated by PDO when this occurs.
- 当发生这种情况时,单元测试失败,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 个解决方案
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测试助手现在它是无害的,您可以继续测试。