Skip to content

Commit 4b98dff

Browse files
committed
Replace loop in setUp()
1 parent c41263f commit 4b98dff

File tree

2 files changed

+57
-18
lines changed

2 files changed

+57
-18
lines changed

src/AsyncTestCase.php

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ abstract class AsyncTestCase extends PHPUnitTestCase
2424
/** @var int Minimum runtime in milliseconds. */
2525
private $minimumRuntime = 0;
2626

27+
/** @var bool */
28+
private $setUpInvoked = false;
29+
30+
protected function setUp()
31+
{
32+
$this->setUpInvoked = true;
33+
Loop::set((new Loop\DriverFactory)->create());
34+
\gc_collect_cycles(); // extensions using an event loop may otherwise leak the file descriptors to the loop
35+
}
36+
2737
/**
2838
* @codeCoverageIgnore Invoked before code coverage data is being collected.
2939
*/
@@ -44,29 +54,32 @@ final public function runAsyncTest(...$args)
4454
{
4555
parent::setName($this->realTestName);
4656

57+
if (!$this->setUpInvoked) {
58+
$this->fail(\sprintf(
59+
'%s::setUp() overrides %s::setUp() without calling the parent method',
60+
\str_replace("\0", '@', \get_class($this)), // replace NUL-byte in anonymous class name
61+
self::class
62+
));
63+
}
64+
4765
$returnValue = null;
4866

49-
try {
50-
$start = \microtime(true);
67+
$start = \microtime(true);
5168

52-
Loop::run(function () use (&$returnValue, $args) {
53-
try {
54-
$returnValue = yield call([$this, $this->realTestName], ...$args);
55-
} finally {
56-
if (isset($this->timeoutId)) {
57-
Loop::cancel($this->timeoutId);
58-
}
69+
Loop::run(function () use (&$returnValue, $args) {
70+
try {
71+
$returnValue = yield call([$this, $this->realTestName], ...$args);
72+
} finally {
73+
if (isset($this->timeoutId)) {
74+
Loop::cancel($this->timeoutId);
5975
}
60-
});
61-
62-
$actualRuntime = (int) (\round(\microtime(true) - $start, self::RUNTIME_PRECISION) * 1000);
63-
if ($this->minimumRuntime > $actualRuntime) {
64-
$msg = 'Expected test to take at least %dms but instead took %dms';
65-
$this->fail(\sprintf($msg, $this->minimumRuntime, $actualRuntime));
6676
}
67-
} finally {
68-
Loop::set((new Loop\DriverFactory)->create());
69-
\gc_collect_cycles(); // extensions using an event loop may otherwise leak the file descriptors to the loop
77+
});
78+
79+
$actualRuntime = (int) (\round(\microtime(true) - $start, self::RUNTIME_PRECISION) * 1000);
80+
if ($this->minimumRuntime > $actualRuntime) {
81+
$msg = 'Expected test to take at least %dms but instead took %dms';
82+
$this->fail(\sprintf($msg, $this->minimumRuntime, $actualRuntime));
7083
}
7184

7285
return $returnValue;

test/InvalidAsyncTestCaseTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Amp\PHPUnit\Test;
4+
5+
use Amp\PHPUnit\AsyncTestCase;
6+
use PHPUnit\Framework\AssertionFailedError;
7+
8+
class InvalidAsyncTestCaseTest extends AsyncTestCase
9+
{
10+
protected function setUp()
11+
{
12+
// No call to parent::setUp()
13+
14+
$this->expectException(AssertionFailedError::class);
15+
$this->expectExceptionMessage('without calling the parent method');
16+
}
17+
18+
/**
19+
* @expectedException \Error
20+
* @expectedExceptionMessage without calling the parent method
21+
*/
22+
public function testMethod()
23+
{
24+
// Test will fail because setUp() did not call the parent method
25+
}
26+
}

0 commit comments

Comments
 (0)