phpunit 不能序列化或反序列化 PDO 实例



我将PHPUnit与processIsolation="true"一起使用,因为我需要在我正在测试的代码中设置cookie值,如果没有processIsolation="true",它就无法完成。但是在我的一个测试用例中,我收到错误:

PHPUnit_Framework_Exception: [10-May-2018 15:23:28 UTC] PHP Fatal error:  Uncaught PDOException: You cannot serialize or unserialize PDO instances in -:394
Stack trace:
#0 [internal function]: PDO->__sleep()
#1 -(394): serialize(Array)
#2 -(536): __phpunit_run_isolated_test()
#3 {main}
thrown in - on line 394

测试用例:

public function testUserCookieIsSavedToClicksTable()
{
$cookie = sha1('12345');
$_COOKIE['user_cookie'] = $cookie;
$offerId = 1;
$tx = $this->getTx($offerId);
// Go
$this->controller = new ClickController(new Click(new Database(Cache::getInstance()), new Queue, new RedisStorage()));
$this->runLocal([1, $this->userId], null);
$sql = 'select * from clicks order by id desc limit 1';
$click = $this->db->query($sql, [], 'fetch');
$this->assertEquals($tx, $click['tx_id']);
$this->assertEquals($click['user_cookie'], $cookie);
}

调用任何$this->assertEquals($tx, $click['tx_id']);$this->assertEquals($click['user_cookie'], $cookie);时都会引发此错误。但我可以var_dump这些断言中使用的任何变量。

我从这里尝试了所有解决方案,但它们对我不起作用

进程隔离要求要隔离的进程中的所有对象都可以序列化/取消序列化。

您看到的错误是关于不支持 PHP 对象序列化/反序列化的特定对象。

首先,这意味着在您询问的情况下,您不能使用该测试的进程隔离。

如果您稍微咀嚼一下并改变一些关于这里发生的事情的想法,以及为什么某些对象(如数据库连接(通常不能序列化,为什么进程隔离也可能使用序列化,它可能会想到为什么数据库连接的进程隔离毕竟不是一个好主意。

因此,即使您在这里看到导致错误的技术限制,最后我会说不在同一测试套件中在隔离进程中运行基于数据库连接的测试是完全有意义的。

这也许不是你所希望的答案。

也许分而治之在这里是有意义的:将那些进程隔离工作的测试放入它自己的测试套件中,并为其配置进程隔离。

对于另一个,在他们自己的测试套件中也做同样的事情。

PHPUnit XML配置文件提供了这些设置,有时甚至需要有多个这样的XML配置文件,有点取决于所使用的Phpunit版本,但也取决于测试运行器的配置设置。

这可能是db组件中的错误。它应该实现__sleep()方法以确保PDO实例不会随之序列化(并且可能实现__wakeup()以在反序列化后重新连接(。

您没有分享有关db组件的任何信息,但这可以通过这样的事情来实现:

public function __sleep() {
$fields = (array) $this;
unset($fields['pdo']);
return array_keys($fields);
}

最新更新