Context
Researching whether phpdb-mysql's Connection class can be made final ahead of its 1.0.0 release. This will need a resource-factory contract designed here in php-db/phpdb, since the same problem will apply to every driver package. Still tracing the upstream interfaces and deciding on an approach, not rushed.
Root cause of the test failures
phpdb-mysql's test/unit/ConnectionTest.php::createMockConnection() uses a PHPUnit partial mock:
$connection = $this->getMockBuilder(Connection::class)
->onlyMethods(['createResource'])
->setConstructorArgs([$params])
->getMock();
onlyMethods() partial mocking works by generating a real subclass of Connection at runtime with the specified method overridden. Marking Connection final breaks this, since PHP does not allow subclassing a final class. This throws:
PHPUnit\Framework\MockObject\Generator\ClassIsFinalException: Class "PhpDb\Mysql\Connection" is declared "final" and cannot be doubled
Also confirmed that calling setResource() with a fake resource before connect() does not work as a substitute. connect()'s first line is if ($this->resource instanceof mysqli) { return $this; }. Once a resource is set, connect() treats that as already connected and returns immediately, skipping the DSN and SSL flag building logic and the real_connect() call that the tests need to exercise.
Context
Researching whether
phpdb-mysql'sConnectionclass can be madefinalahead of its 1.0.0 release. This will need a resource-factory contract designed here inphp-db/phpdb, since the same problem will apply to every driver package. Still tracing the upstream interfaces and deciding on an approach, not rushed.Root cause of the test failures
phpdb-mysql'stest/unit/ConnectionTest.php::createMockConnection()uses a PHPUnit partial mock:onlyMethods()partial mocking works by generating a real subclass ofConnectionat runtime with the specified method overridden. MarkingConnectionfinalbreaks this, since PHP does not allow subclassing a final class. This throws:Also confirmed that calling
setResource()with a fake resource beforeconnect()does not work as a substitute.connect()'s first line isif ($this->resource instanceof mysqli) { return $this; }. Once a resource is set,connect()treats that as already connected and returns immediately, skipping the DSN and SSL flag building logic and thereal_connect()call that the tests need to exercise.