Amp\Loop\InvalidWatcherError : Cannot reference an invalid watcher identifier: 'e'
I try use PHPUnit with Postgres adapter. But I catch error.
amphp/postgres v1.4.3
Example code:
<?php
use Amp\PHPUnit\AsyncTestCase;
use Amp\Postgres\ConnectionConfig;
$connection = \Amp\Postgres\pool(ConnectionConfig::fromString("host=localhost port=5432 dbname=rees46_test user=rails password=rails"), 5);
class BarTest extends AsyncTestCase {
public function test() {
global $connection;
$result = yield $connection->execute('SELECT 1 AS c');
if( yield $result->advance() ) {
$this->assertSame(1, $result->getCurrent()['c']);
}
}
public function test2() {
global $connection;
$result = yield $connection->execute('SELECT 1 AS c');
if( yield $result->advance() ) {
$this->assertSame(1, $result->getCurrent()['c']);
}
}
}
Test log:
Testing started at 23:04 ...
PHPUnit 9.5.11 by Sebastian Bergmann and contributors.
Runtime: PHP 8.0.12
Configuration: /project/phpunit.xml
Amp\Loop\InvalidWatcherError : Cannot reference an invalid watcher identifier: 'e'
/project/vendor/amphp/amp/lib/Loop/Driver.php:516
/project/vendor/amphp/amp/lib/Loop.php:322
/project/vendor/amphp/postgres/src/PgSqlHandle.php:269
/project/vendor/amphp/postgres/src/PgSqlHandle.php:381
/project/vendor/amphp/amp/lib/Coroutine.php:67
/project/vendor/amphp/amp/lib/functions.php:96
/project/vendor/amphp/postgres/src/PgSqlHandle.php:382
/project/vendor/amphp/postgres/src/Connection.php:79
/project/vendor/amphp/postgres/src/Connection.php:109
/project/vendor/amphp/postgres/src/Pool.php:83
/project/vendor/amphp/sql-common/src/ConnectionPool.php:363
/project/vendor/amphp/amp/lib/Coroutine.php:67
/project/vendor/amphp/amp/lib/functions.php:96
/project/vendor/amphp/sql-common/src/ConnectionPool.php:382
/project/test/BarTest.php:21
/project/vendor/amphp/amp/lib/Coroutine.php:67
/project/vendor/amphp/phpunit-util/src/AsyncTestCase.php:278
/project/vendor/amphp/phpunit-util/src/AsyncTestCase.php:137
/project/vendor/amphp/amp/lib/Coroutine.php:118
/project/vendor/amphp/amp/lib/Success.php:41
/project/vendor/amphp/amp/lib/Coroutine.php:151
/project/vendor/amphp/phpunit-util/src/AsyncTestCase.php:68
/project/vendor/amphp/amp/lib/Loop/Driver.php:119
/project/vendor/amphp/amp/lib/Loop/Driver.php:72
/project/vendor/amphp/amp/lib/Loop/EventDriver.php:211
/project/vendor/amphp/amp/lib/Loop.php:95
/project/vendor/amphp/phpunit-util/src/AsyncTestCase.php:96
/project/vendor/amphp/phpunit-util/src/AsyncTestCase.php:46
Time: 00:00.110, Memory: 10.00 MB
ERRORS!
Tests: 2, Assertions: 1, Errors: 1.
But for this example, tests works correctly:
<?php
use Amp\PHPUnit\AsyncTestCase;
use Amp\Postgres\ConnectionConfig;
class BarTest extends AsyncTestCase {
public function test() {
$connection = \Amp\Postgres\pool(ConnectionConfig::fromString("host=localhost port=5432 dbname=rees46_test user=rails password=rails"), 5);
$result = yield $connection->execute('SELECT 1 AS c');
if( yield $result->advance() ) {
$this->assertSame(1, $result->getCurrent()['c']);
}
}
public function test2() {
$connection = \Amp\Postgres\pool(ConnectionConfig::fromString("host=localhost port=5432 dbname=rees46_test user=rails password=rails"), 5);
$result = yield $connection->execute('SELECT 1 AS c');
if( yield $result->advance() ) {
$this->assertSame(1, $result->getCurrent()['c']);
}
}
}
Log:
Testing started at 23:06 ...
PHPUnit 9.5.11 by Sebastian Bergmann and contributors.
Runtime: PHP 8.0.12
Configuration: /Users/nixx/Projects/rees46-core/phpunit.xml
Time: 00:00.113, Memory: 8.00 MB
OK (2 tests, 2 assertions)
AsyncTestCase will use a separate event loop per test for isolation purposes, but that makes previous watchers invalid that are still supposed to be active in global state. We've removed swapping the event loop instance in the new major version for that reason.
Do I need to connect to the DB every time I run a test? This is terrible.
Currently, that's how it is when using AsyncTestCase, yes.
The event loop is no longer discarded between each test in AMPHP v3 and therefore in v2.x of this library, so this should no longer be an issue.
That being said, be careful about sharing state between test and that you're doing it intentionally, not accidentally.