【问题标题】:PDO connection is not closed when phpunit is running with symfony 2.X当 phpunit 使用 symfony 2.X 运行时,PDO 连接没有关闭
【发布时间】:2013-05-29 08:16:58
【问题描述】:

我们有大约 180 个单元测试实现 webtestcase 类,并且测试在控制器上运行。

但是,当我们运行单元测试时,它们打开了太多与 db 的连接。由于在第 120 次测试后有太多的活动 tcp 连接测试失败。测试运行时所有连接都处于活动状态。

在tearDown函数中我们调用了实体管理器的close函数,但是什么都没有,没有任何影响。我认为有一些类保持连接对象引用。

因为在 php 手册中提到当对象分配为 null 时 pdo 连接关闭。我们也这样做,但没有改变。 P.S:我们的单元测试是功能测试。在控制器上工作并与数据库集成,没有模拟对象

我们的错误在哪里?我们该如何解决这个问题?

这是我在 config_test.yml 中的连接参数

imports:
    - { resource: config_dev.yml }

framework:
    test: ~
    session:
        storage_id: session.storage.mock_file

web_profiler:
    toolbar: false
    intercept_redirects: false

doctrine:
    dbal:
        driver: pdo_mysql
        port: 3306
        host: localhost
        dbname: mydb
        user: myuser
        password: mypass
        charset: UTF8

【问题讨论】:

  • 我们可以看看您是如何在 config.yml 文件和/或 parameters.yml 中定义连接的吗?
  • @j0k 我添加到问题中
  • 前段时间我也遇到过类似的问题。问题是由于未完成的交易而发生的。您是否使用显式事务(我的意思是开始提交/回滚)?如果是这样,请确保您始终完成它。
  • 嗯,我还有一个猜测。你如何关闭这些连接?您是否从客户那里关闭实体经理?如果你不这样做 - 你应该从客户端关闭实体管理器: $this->client->getContainer()->get('doctrine.orm.entity_manager')->close();
  • @Cyprian 我没有交易。如果默认情况下学说使用事务性,那么我不知道。是的,我按照你说的关闭了连接。

标签: symfony doctrine-orm connection phpunit


【解决方案1】:

你检查你的 phpunit.xml.dist 文件了吗?

我认为你应该看看这个; http://www.slideshare.net/fabpot/unit-and-functional-testing-with-symfony2

确保您的参数与以下相同

<phpunit
    backupGlobals               = "false"
    backupStaticAttributes      = "false"
    colors                      = "true"
    convertErrorsToExceptions   = "true"
    convertNoticesToExceptions  = "true"
    convertWarningsToExceptions = "true"
    processIsolation            = "true"
    stopOnFailure               = "false"
    syntaxCheck                 = "false" 
    bootstrap                   = "bootstrap.php.cache" >

【讨论】:

  • 非常感谢。我找到了解决方案。显然 processIsolation 参数导致了问题。这是错误的,因为整个测试都在一个进程上工作,我认为它保留了参数。但是在我将其更改为 true 后,每次测试结束后连接都会关闭。 @bulutcagatay
  • 有趣的是,这带来了另一个问题:“Uncaught PDOException: You cannot serialize or unserialize PDO instances”。
  • 这一切都很好,但是当你将 processIsolation 设置为“true”时,任何断言失败都会导致一个关于无法序列化闭包的模糊错误。
【解决方案2】:

启用进程隔离的副作用是使测试套件的执行速度变得异常缓慢。

更好的方法是明确告诉 Doctrine 关闭其连接,无论是在测试 tearDown、tearDownAfterClass 或任何这样注释的方法上,例如:

trait CloseConnectionAfterTestTrait {
    /** @after */
    public function avoidExhaustingDbConnections()
    {
        if(!empty($this->em)){
            $this->em->getConnection()->close();
        }
    }
}

在此示例中,由消费者将其拥有的任何实体管理器实例保存为$this-&gt;em。但是如果/因为您使用 Doctrine,您可能可以通过 static::$kernel-&gt;something 访问 Doctrine 服务来更好地概括代码。

【讨论】:

  • 我已添加代码以在每次测试后关闭连接 - 但仍然没有效果...
猜你喜欢
  • 2018-08-20
  • 2013-09-21
  • 2019-07-20
  • 2013-08-19
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多