如何使用静态调用对函数进行单元测试
How to unit test a function with a static call
我正在编写一个使用 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工作,也看了一下moquery。我真的不明白我是如何完成这项工作的:
这个嘲弄测试不起作用,但我不确定它应该如何:
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,所以我不知道模拟是如何发生的。
这是我的问题:
- 甚至可以测试像这样静态调用的函数吗?
- 如果是这样,嘲笑 a/the 是这样做的方法吗?
- 如果是这样,我上面的测试有什么问题?
- 是的,有可能。
- 是的,Mockery(以及 PHPUnit 本身)可以做到这一点(使用 "fake autoloading")。检查 this article 了解更多信息。
- 我在你的测试中没有发现任何问题。请检查此 repo。我尝试重现您的问题,但一切正常。
我正在编写一个使用 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工作,也看了一下moquery。我真的不明白我是如何完成这项工作的:
这个嘲弄测试不起作用,但我不确定它应该如何:
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,所以我不知道模拟是如何发生的。
这是我的问题:
- 甚至可以测试像这样静态调用的函数吗?
- 如果是这样,嘲笑 a/the 是这样做的方法吗?
- 如果是这样,我上面的测试有什么问题?
- 是的,有可能。
- 是的,Mockery(以及 PHPUnit 本身)可以做到这一点(使用 "fake autoloading")。检查 this article 了解更多信息。
- 我在你的测试中没有发现任何问题。请检查此 repo。我尝试重现您的问题,但一切正常。