Doctrine 的实体管理器崩溃并保持关闭

2022-01-25 00:00:00 php phpunit doctrine-orm

所以,当我在我的 ZF/Doctrine 应用程序上运行测试时,一些测试碰巧破坏了 Doctrine Entity Manager,并且由于 EM 被关闭,所有顺序测试都失败了.

So, when I run tests on my ZF/Doctrine application, some tests happen to break the Doctrine Entity Manager, and all the sequential tests fail due to EM being closed.

我在我的测试/bootstrap.php 中设置了 EM:

I set the EM up in my tests/bootstrap.php:

$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap();
(...)
$bootstrap = $application->getBootstrap();
$em = $bootstrap->getResource('doctrinemanager');

然后我在测试 setUp() 函数中设置它($this->_service 是被测试的服务):

Then I set it inside the test setUp() function ($this->_service is the service being tested):

$em = App::getEntityManager();
$this->_em = clone $em;
$this->_service->setEm($this->_em);

然后,当我运行一个导致 EM 抛出异常并关闭的测试时(这对我来说是正确的行为),它在所有测试中都保持关闭状态,当然这些测试由于 EM 被关闭而失败.这不是我期望的测试行为,你可以猜到.

And then when I run a test that causes EM to throw an exception and close (and that's the correct behaviour for me), it stays closed throughout all the tests which of course fail due to EM being closed. That's just not the behaviour I expect for tests, as you can guess.

我尝试在将 EM 设置到服务之前克​​隆它,但没有成功.

I tried cloning the EM before setting it in the service, but it didn't work.

是否有一种简单的方法可以使用某些 Doctrine 方法重新打开 EM?

Is there an easy way to reopen the EM maybe using some Doctrine methods?

推荐答案

不,反正我不知道.解决此问题的最简单方法是简单地(重新)引导您的应用程序以在每个测试的设置阶段运行.因此,每个测试都会获得一个新的 $application 实例和一个全新的 $em 实例.这就是快速修复.

No, not that I know of anyway. The simplest way around this would be to simply (re-)bootstrap you application to run in the setup phase of every test. So, every test gets a new $application instance and a fresh, new $em along with it. That's the quick fix.

正确的解决方案可能是将测试与 Zend_Application 分离.允许您的测试使用简单的实体管理器运行,可能使用模拟连接或到 内存中的 SQLite 数据库.在您的测试设置阶段仅创建此实体管理器,因此每个测试都会获得一个新的实体管理器.这类似于上面的快速修复,除了现在您只专门为测试创建一个实体管理器,而不是为每个测试引导您的整个应用程序.它更精简、更简单.

The proper solution probably is to decouple your tests from your Zend_Application. Allow your tests to run with a simple entity manager, possibly using a mock connection or a connection to an in-memory SQLite database. Create only this entity manager in your test setup phase, so every test gets a new entity manager. This is similar to the quick fix above, except now you only specifically create an entity manager for testing instead of bootstrapping your entire application for every test. It's leaner and simpler.

相关文章