Skip to content

Commit 7c97bdc

Browse files
authored
Merge pull request #39 from clue-labs/tests
Simplify test structure, improve test isolation and remove dbunit
2 parents f0506ef + 7039687 commit 7c97bdc

File tree

9 files changed

+111
-96
lines changed

9 files changed

+111
-96
lines changed

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ The test suite contains a number of functional integration tests that send
107107
actual test SQL queries against your local database and thus rely on a local
108108
MySQL test database with appropriate write access.
109109
The test suite creates and modifies a test table in this database, so make sure
110-
to not a production database!
110+
to not use a production database!
111111
You can change your test database credentials by passing these ENV variables:
112112

113113
```bash
@@ -118,6 +118,15 @@ $ export DB_PASSWD=test
118118
$ export DB_DBNAME=test
119119
```
120120

121+
For example, to create an empty test database, you can also use a temporary
122+
[`mysql` Docker image](https://hub.docker.com/_/mysql/) like this:
123+
124+
```bash
125+
$ docker run -it --rm --net=host \
126+
-e MYSQL_RANDOM_ROOT_PASSWORD=yes -e MYSQL_DATABASE=test \
127+
-e MYSQL_USER=test -e MYSQL_PASSWORD=test mysql
128+
```
129+
121130
To run the test suite, go to the project root and run:
122131

123132
```bash

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
"react/socket": "^1.0 || ^0.8"
1010
},
1111
"require-dev": {
12-
"phpunit/dbunit": "1.4.*",
13-
"ext-pdo_mysql": "*"
12+
"phpunit/phpunit": "^4.8.35"
1413
},
1514
"autoload": {
1615
"psr-4": {

data/book.sql

Lines changed: 0 additions & 15 deletions
This file was deleted.

phpunit.xml.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
</whitelist>
2424
</filter>
2525
<php>
26-
<env name="DB_HOST" value="localhost"/>
26+
<env name="DB_HOST" value="127.0.0.1"/>
2727
<env name="DB_PORT" value="3306"/>
2828
<env name="DB_USER" value="test" />
2929
<env name="DB_PASSWD" value="test" />

tests/BaseTestCase.php

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,13 @@
22

33
namespace React\Tests\MySQL;
44

5-
class BaseTestCase extends \PHPUnit_Extensions_Database_TestCase
6-
{
7-
private static $pdo;
8-
private $conn;
9-
10-
protected function getConnection()
11-
{
12-
if ($this->conn === null) {
13-
if (self::$pdo == null) {
14-
$conf = $this->getConnectionOptions();
15-
$dsn = 'mysql:host=' . $conf['host'] . ';port=' . $conf['port'] . ';dbname=' . $conf['dbname'];
16-
self::$pdo = new \PDO($dsn, $conf['user'], $conf['passwd']);
17-
}
18-
19-
self::$pdo->query('
20-
CREATE TABLE IF NOT EXISTS `book` (
21-
`id` INT(11) NOT NULL AUTO_INCREMENT,
22-
`name` VARCHAR(255) NOT NULL,
23-
`isbn` VARCHAR(255) NULL,
24-
`author` VARCHAR(255) NULL,
25-
`created` INT(11) NULL,
26-
PRIMARY KEY (`id`)
27-
)
28-
');
29-
30-
$this->conn = $this->createDefaultDBConnection(self::$pdo, ':memory:');
31-
}
32-
33-
return $this->conn;
34-
}
35-
36-
protected function getDataSet()
37-
{
38-
return new \PHPUnit_Extensions_Database_DataSet_YamlDataSet(__DIR__ . '/dataset.yaml');
39-
}
5+
use PHPUnit\Framework\TestCase;
406

7+
class BaseTestCase extends TestCase
8+
{
419
protected function getConnectionOptions()
4210
{
11+
// can be controlled through ENV or by changing defaults in phpunit.xml
4312
return [
4413
'host' => getenv('DB_HOST'),
4514
'port' => (int)getenv('DB_PORT'),
@@ -49,6 +18,20 @@ protected function getConnectionOptions()
4918
];
5019
}
5120

21+
protected function getDataTable()
22+
{
23+
return <<<SQL
24+
CREATE TABLE `book` (
25+
`id` INT(11) NOT NULL AUTO_INCREMENT,
26+
`name` VARCHAR(255) NOT NULL,
27+
`isbn` VARCHAR(255) NULL,
28+
`author` VARCHAR(255) NULL,
29+
`created` INT(11) NULL,
30+
PRIMARY KEY (`id`)
31+
)
32+
SQL;
33+
}
34+
5235
protected function expectCallableOnce()
5336
{
5437
$mock = $this->getMockBuilder('stdClass')->setMethods(array('__invoke'))->getMock();

tests/ConnectionTest.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,11 @@ public function testConnectWithInvalidPassRejectsWithAuthenticationError()
3030

3131
$conn->on('error', $this->expectCallableOnce());
3232

33-
$conn->connect(function ($err, $conn) use ($loop, $options) {
34-
$this->assertEquals(sprintf(
35-
"Access denied for user '%s'@'%s' (using password: YES)",
36-
$options['user'],
37-
$options['host']
38-
), $err->getMessage());
33+
$conn->connect(function ($err, $conn) use ($loop) {
34+
$this->assertRegExp(
35+
"/^Access denied for user '.*?'@'.*?' \(using password: YES\)$/",
36+
$err->getMessage()
37+
);
3938
$this->assertInstanceOf('React\MySQL\Connection', $conn);
4039
$this->assertEquals(Connection::STATE_AUTHENTICATE_FAILED, $conn->getState());
4140
});

tests/NoResultQueryTest.php

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,70 @@
22

33
namespace React\Tests\MySQL;
44

5-
class NoResultQueryTest extends BaseTestCase
5+
class NoResultQueryTest extends BaseTestCase
66
{
7-
public function testUpdateSimple()
7+
public function setUp()
88
{
99
$loop = \React\EventLoop\Factory::create();
1010

1111
$connection = new \React\MySQL\Connection($loop, $this->getConnectionOptions());
12+
$connection->connect(function () {});
13+
14+
// re-create test "book" table
15+
$connection->query('DROP TABLE IF EXISTS book');
16+
$connection->query($this->getDataTable());
17+
18+
$connection->close();
19+
$loop->run();
20+
}
21+
22+
public function testUpdateSimpleNonExistentReportsNoAffectedRows()
23+
{
24+
$loop = \React\EventLoop\Factory::create();
1225

26+
$connection = new \React\MySQL\Connection($loop, $this->getConnectionOptions());
1327
$connection->connect(function () {});
14-
$that = $this;
1528

16-
$connection->query('update book set created=999 where id=1', function ($command, $conn) use ($loop) {
29+
$connection->query('update book set created=999 where id=999', function ($command, $conn) {
1730
$this->assertEquals(false, $command->hasError());
18-
$this->assertEquals(1, $command->affectedRows);
19-
$loop->stop();
31+
$this->assertEquals(0, $command->affectedRows);
2032
});
33+
34+
$connection->close();
2135
$loop->run();
2236
}
2337

24-
public function testInsertSimple()
38+
public function testInsertSimpleReportsFirstInsertId()
2539
{
2640
$loop = \React\EventLoop\Factory::create();
2741

2842
$connection = new \React\MySQL\Connection($loop, $this->getConnectionOptions());
43+
$connection->connect(function () {});
2944

45+
$connection->query("insert into book (`name`) values ('foo')", function ($command, $conn) {
46+
$this->assertEquals(false, $command->hasError());
47+
$this->assertEquals(1, $command->affectedRows);
48+
$this->assertEquals(1, $command->insertId);
49+
});
50+
51+
$connection->close();
52+
$loop->run();
53+
}
54+
55+
public function testUpdateSimpleReportsAffectedRow()
56+
{
57+
$loop = \React\EventLoop\Factory::create();
58+
59+
$connection = new \React\MySQL\Connection($loop, $this->getConnectionOptions());
3060
$connection->connect(function () {});
3161

32-
$connection->query("insert into book (`name`) values('foo')", function ($command, $conn) use ($loop) {
62+
$connection->query("insert into book (`name`) values ('foo')");
63+
$connection->query('update book set created=999 where id=1', function ($command, $conn) {
3364
$this->assertEquals(false, $command->hasError());
3465
$this->assertEquals(1, $command->affectedRows);
35-
$this->assertEquals(3, $command->insertId);
36-
$loop->stop();
3766
});
67+
68+
$connection->close();
3869
$loop->run();
3970
}
4071
}

tests/ResultQueryTest.php

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@ public function testSimpleSelect()
1111
$connection = new \React\MySQL\Connection($loop, $this->getConnectionOptions());
1212
$connection->connect(function () {});
1313

14-
$connection->query('select * from book', function ($command, $conn) use ($loop) {
14+
// re-create test "book" table
15+
$connection->query('DROP TABLE IF EXISTS book');
16+
$connection->query($this->getDataTable());
17+
$connection->query("insert into book (`name`) values ('foo')");
18+
$connection->query("insert into book (`name`) values ('bar')");
19+
20+
$connection->query('select * from book', function ($command, $conn) {
1521
$this->assertEquals(false, $command->hasError());
16-
$this->assertEquals(2, count($command->resultRows));
22+
$this->assertCount(2, $command->resultRows);
1723
$this->assertInstanceOf('React\MySQL\Connection', $conn);
18-
$loop->stop();
1924
});
25+
26+
$connection->close();
2027
$loop->run();
2128
}
2229

@@ -29,38 +36,49 @@ public function testInvalidSelect()
2936
$connection = new \React\MySQL\Connection($loop, $options);
3037
$connection->connect(function () {});
3138

32-
$connection->query('select * from invalid_table', function ($command, $conn) use ($loop, $db) {
39+
$connection->query('select * from invalid_table', function ($command, $conn) use ($db) {
3340
$this->assertEquals(true, $command->hasError());
3441
$this->assertEquals("Table '$db.invalid_table' doesn't exist", $command->getError()->getMessage());
35-
36-
$loop->stop();
3742
});
43+
44+
$connection->close();
3845
$loop->run();
3946
}
4047

4148
public function testEventSelect()
4249
{
50+
$this->expectOutputString('result.result.results.end.');
4351
$loop = \React\EventLoop\Factory::create();
4452

4553
$connection = new \React\MySQL\Connection($loop, $this->getConnectionOptions());
4654
$connection->connect(function () {});
4755

56+
// re-create test "book" table
57+
$connection->query('DROP TABLE IF EXISTS book');
58+
$connection->query($this->getDataTable());
59+
$connection->query("insert into book (`name`) values ('foo')");
60+
$connection->query("insert into book (`name`) values ('bar')");
61+
4862
$command = $connection->query('select * from book');
4963
$command->on('results', function ($results, $command, $conn) {
5064
$this->assertEquals(2, count($results));
5165
$this->assertInstanceOf('React\MySQL\Commands\QueryCommand', $command);
5266
$this->assertInstanceOf('React\MySQL\Connection', $conn);
67+
echo 'results.';
5368
});
5469
$command->on('result', function ($result, $command, $conn) {
5570
$this->assertArrayHasKey('id', $result);
5671
$this->assertInstanceOf('React\MySQL\Commands\QueryCommand', $command);
5772
$this->assertInstanceOf('React\MySQL\Connection', $conn);
73+
echo 'result.';
5874
})
59-
->on('end', function ($command, $conn) use ($loop) {
75+
->on('end', function ($command, $conn) {
6076
$this->assertInstanceOf('React\MySQL\Commands\QueryCommand', $command);
6177
$this->assertInstanceOf('React\MySQL\Connection', $conn);
62-
$loop->stop();
78+
echo 'end.';
6379
});
80+
81+
$connection->close();
6482
$loop->run();
6583
}
6684

@@ -70,13 +88,14 @@ public function testSelectAfterDelay()
7088

7189
$connection = new \React\MySQL\Connection($loop, $this->getConnectionOptions());
7290

73-
$callback = function () use ($connection, $loop) {
74-
$connection->query('select 1+1', function ($command, $conn) use ($loop) {
91+
$callback = function () use ($connection) {
92+
$connection->query('select 1+1', function ($command, $conn) {
7593
$this->assertEquals(false, $command->hasError());
7694
$this->assertEquals([['1+1' => 2]], $command->resultRows);
77-
$loop->stop();
7895
});
96+
$connection->close();
7997
};
98+
8099
$timeoutCb = function () use ($loop) {
81100
$loop->stop();
82101
$this->fail('Test timeout');
@@ -85,7 +104,11 @@ public function testSelectAfterDelay()
85104
$connection->connect(function ($err, $conn) use ($callback, $loop, $timeoutCb) {
86105
$this->assertEquals(null, $err);
87106
$loop->addTimer(0.1, $callback);
88-
$loop->addTimer(1, $timeoutCb);
107+
108+
$timeout = $loop->addTimer(1, $timeoutCb);
109+
$conn->on('close', function () use ($loop, $timeout) {
110+
$loop->cancelTimer($timeout);
111+
});
89112
});
90113

91114
$loop->run();

tests/dataset.yaml

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)