【发布时间】:2018-07-31 09:49:46
【问题描述】:
在我的 PHP 应用程序中,我稍后在数据访问中使用 Doctrine ORM。在这一层中,我有一些服务,例如通常使用 Doctrines EntityManager 的存储库。在这些服务中,进行某种形式修改的方法通常遵循以下模式:
public function modifyStuff( /* ... */ ) {
try {
$stuff = $this->entityManager->find( /* ... */ )
}
catch ( ORMException $ex ) {
/* ... */
}
// Poke at $stuff
try {
$this->entityManager->persist( $stuff );
$this->entityManager->flush();
}
catch ( ORMException $ex ) {
/* code that needs to be tested */
}
}
我正在尝试找到一种方法来测试第二个 catch 块中的代码:处理写入失败的代码。所以在我的测试中,我需要在写东西时让 EntityManager 抛出。当然,我想在我的测试中尽量减少对这个存储库的实现(即使用哪些学说方法)和 EntityManager 接口和实现本身的绑定。理想情况下我可以做类似的事情
$entityManager = new TestEntityManager();
$entityManager->throwOnWrite();
之后,EntityManager 将正常运行,但它会在写入时抛出。 (我的存储库有这样的测试替身。)
我尝试使用 PHPUnit mock API 如下:
$entityManager = $this->getMockBuilder( EntityManager::class )->disableOrgninalConstructor()->getMock()
$entityManager->expects( $this->any() )
->method( 'persist' )
->willThrowException( new ORMException() );
这并不理想,因为现在我的测试绑定到 persist 方法,尽管这不是什么大问题。这不起作用,因为服务要运行它的构造函数需要一些参数。然后我尝试了
$entityManager =
$this->getMockBuilder( EntityManager::class )
->setConstructorArgs( [
$this->entityManager->getConnection(),
$this->entityManager->getConfiguration(),
$this->entityManager->getEventManager()
] )
->getMock();
发现 EntityManager 的构造函数是不公开的。所以看来我将无法使用 PHPUnit 模拟 API。
关于如何让 EntityManager 在写入时抛出,或者以其他方式测试应该处理这种情况的代码的任何想法?
【问题讨论】:
-
可能是stackoverflow.com/a/43083956/5769763?作为评论发布,因为我没有时间尝试实际验证这是您的意思以及是否有效。
-
这种方法是不可能的,因为服务需要它的构造函数参数,而 PHPUnit 显然无法将构造函数参数填充到非公共构造函数中。
标签: php doctrine-orm phpunit