【问题标题】:How to unit test a function with a static call如何使用静态调用对函数进行单元测试
【发布时间】:2018-08-29 03:52:04
【问题描述】:

我正在编写一个使用 Doctrine DBAL 系统的函数。这里使用静态函数连接如下:

$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);

我想用一个模拟单元测试这个功能。

public function openNewConnection(string $database_name): Connection
{
       try {
            // some logic where I check the validity of the connection
            $this->connection = DriverManager::getConnection($connection_params, $config);
            break;
        } catch (Exception $e) {
            // catch the different errors that could be created
        }
    return $this->connection;
}

我不能使用依赖注入来解决这个问题:

  • 我正在动态生成$connectionParams:我需要在这里拨打电话
  • 没有(正确的)方法可以非静态调用此函数:我只是将问题转移到别处

我一直在phpunit工作,我也看过嘲讽。我真的不明白我是如何完成这项工作的:

这个嘲弄测试不起作用,但我不确定它应该如何:

public function testConnect(): void
{
    // mocked connection return
    $mocked_connection = new Connection([], $this->driver);

    // use Mockery to simulate static call
    $driver_manager = Mockery::mock('alias:\Doctrine\DBAL\DriverManager');
    $driver_manager->shouldReceive('getConnection')
                   ->once()
                   ->andReturn($mocked_connection);

    $database = new Database($this->database_configuration_file);
    $database->openNewConnection('test_db_cluster_01');

    $this->assertEquals($mocked_connection, $database->getConnection());
}

据我所知,$database 甚至不知道 $driver_manager,所以我不知道模拟是如何发生的。

这是我的问题:

  • 是否可以像这样测试静态调用的函数?
  • 如果是这样,嘲讽是一种/这样做的方式吗?
  • 如果是这样,我上面的测试有什么问题?

【问题讨论】:

  • (这不是答案)实际上,您可以在您的情况下使用依赖注入。您可以使用$this->connectionFactory->getConnection($connectionParams),而不是调用DriverManager::getConnection()。现在您可以注入(并在测试中模拟)$connectionFactory
  • 不,因为 $connectionParams 不是外部已知的。 openNewConnection 函数的目的是解析多个连接参数并进行连接。虽然我可以将“连接位”分解为一个单独的函数,但这并不能阻止连接仍然是静态的事实。我想模拟静态调用。

标签: php unit-testing doctrine mockery dbal


【解决方案1】:
  1. 是的,有可能。
  2. 是的,Mockery(以及 PHPUnit 本身)可以做到这一点(使用“假自动加载”)。更多信息请查看this article
  3. 我在您的测试中没有发现任何问题。请检查此repo。我试图重现您的问题,但一切正常。

【讨论】:

  • 标记为正确。一些很好的信息。我明白为什么我的连接失败了......然后我在连接上运行更多方法,它确实尝试了数据库连接。
猜你喜欢
  • 2020-09-06
  • 1970-01-01
  • 2017-02-16
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多