I have a function I am writing that uses the Doctrine DBAL system. This uses a static function to connect as follows:
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
I want to unit test this functionality with a mock.
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;
}
I cannot use dependency injection as a way round this as:
- I am dynamically generating
$connectionParams: I need to make the call here - there is no (proper) way to non statically call this function : I would just be moving the problem elsewhere
I've been working in phpunit, and I've also had a look at mockery. I don't really see how I am meant to make this work:
This mockery test doesn't work, but I'm unsure of how it should:
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());
}
From what I can see, the $database isn't even aware of $driver_manager, so I don't see how the mocking would happen.
Here's my question:
- Is it even possible to test a function called statically like this?
- If so, is mockery a/the way to do this?
- If so, what is wrong with my above test?
DriverManager::getConnection()you can use$this->connectionFactory->getConnection($connectionParams). Now you can inject (and mock in tests) the$connectionFactory. - Ivan Kalita