Skip to content

Commit 920035e

Browse files
bug #60484 [PhpUnitBridge] Clean up mocked features only when @group is present (HypeMC)
This PR was merged into the 7.2 branch. Discussion ---------- [PhpUnitBridge] Clean up mocked features only when ``@group`` is present | Q | A | ------------- | --- | Branch? | 7.2 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | - | License | MIT PR #60174 introduced a bug for tests that don't use the ``@group`` annotation but register mocks manually, e.g. in `setUpBeforeClass`: ```php class ExampleTest extends TestCase { public static function setUpBeforeClass(): void { ClockMock::register(self::class); ClockMock::withClockMock(strtotime('2024-05-20 15:30:00')); } public static function tearDownAfterClass(): void { ClockMock::withClockMock(false); } public function testDate() { self::assertSame('2024-05-20 15:30:00', date('Y-m-d H:i:s')); } public function testTime() { self::assertSame(1716219000, time()); } } ``` `testDate` passes, but after that `FinishedSubscriber` is triggered which cleans up the mock and causes `testTime` to fail. I am not sure what to do about `BeforeTestMethodErroredSubscriber` since the test object is not available in that event. I think it's fine to leave it as is. cc `@xabbuh` Commits ------- ea204b9 [PhpUnitBridge] Clean up mocked features only when group is present
2 parents 80e9b58 + ea204b9 commit 920035e

File tree

3 files changed

+119
-12
lines changed

3 files changed

+119
-12
lines changed

src/Symfony/Bridge/PhpUnit/SymfonyExtension.php

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Bridge\PhpUnit;
1313

14+
use PHPUnit\Event\Code\Test;
15+
use PHPUnit\Event\Code\TestMethod;
1416
use PHPUnit\Event\Test\BeforeTestMethodErrored;
1517
use PHPUnit\Event\Test\BeforeTestMethodErroredSubscriber;
1618
use PHPUnit\Event\Test\Errored;
@@ -19,6 +21,7 @@
1921
use PHPUnit\Event\Test\FinishedSubscriber;
2022
use PHPUnit\Event\Test\Skipped;
2123
use PHPUnit\Event\Test\SkippedSubscriber;
24+
use PHPUnit\Metadata\Group;
2225
use PHPUnit\Runner\Extension\Extension;
2326
use PHPUnit\Runner\Extension\Facade;
2427
use PHPUnit\Runner\Extension\ParameterCollection;
@@ -47,31 +50,36 @@ public function bootstrap(Configuration $configuration, Facade $facade, Paramete
4750
$facade->registerSubscriber(new class implements ErroredSubscriber {
4851
public function notify(Errored $event): void
4952
{
50-
SymfonyExtension::disableClockMock();
51-
SymfonyExtension::disableDnsMock();
53+
SymfonyExtension::disableClockMock($event->test());
54+
SymfonyExtension::disableDnsMock($event->test());
5255
}
5356
});
5457
$facade->registerSubscriber(new class implements FinishedSubscriber {
5558
public function notify(Finished $event): void
5659
{
57-
SymfonyExtension::disableClockMock();
58-
SymfonyExtension::disableDnsMock();
60+
SymfonyExtension::disableClockMock($event->test());
61+
SymfonyExtension::disableDnsMock($event->test());
5962
}
6063
});
6164
$facade->registerSubscriber(new class implements SkippedSubscriber {
6265
public function notify(Skipped $event): void
6366
{
64-
SymfonyExtension::disableClockMock();
65-
SymfonyExtension::disableDnsMock();
67+
SymfonyExtension::disableClockMock($event->test());
68+
SymfonyExtension::disableDnsMock($event->test());
6669
}
6770
});
6871

6972
if (interface_exists(BeforeTestMethodErroredSubscriber::class)) {
7073
$facade->registerSubscriber(new class implements BeforeTestMethodErroredSubscriber {
7174
public function notify(BeforeTestMethodErrored $event): void
7275
{
73-
SymfonyExtension::disableClockMock();
74-
SymfonyExtension::disableDnsMock();
76+
if (method_exists($event, 'test')) {
77+
SymfonyExtension::disableClockMock($event->test());
78+
SymfonyExtension::disableDnsMock($event->test());
79+
} else {
80+
ClockMock::withClockMock(false);
81+
DnsMock::withMockedHosts([]);
82+
}
7583
}
7684
});
7785
}
@@ -88,16 +96,38 @@ public function notify(BeforeTestMethodErrored $event): void
8896
/**
8997
* @internal
9098
*/
91-
public static function disableClockMock(): void
99+
public static function disableClockMock(Test $test): void
92100
{
93-
ClockMock::withClockMock(false);
101+
if (self::hasGroup($test, 'time-sensitive')) {
102+
ClockMock::withClockMock(false);
103+
}
94104
}
95105

96106
/**
97107
* @internal
98108
*/
99-
public static function disableDnsMock(): void
109+
public static function disableDnsMock(Test $test): void
100110
{
101-
DnsMock::withMockedHosts([]);
111+
if (self::hasGroup($test, 'dns-sensitive')) {
112+
DnsMock::withMockedHosts([]);
113+
}
114+
}
115+
116+
/**
117+
* @internal
118+
*/
119+
public static function hasGroup(Test $test, string $groupName): bool
120+
{
121+
if (!$test instanceof TestMethod) {
122+
return false;
123+
}
124+
125+
foreach ($test->metadata() as $metadata) {
126+
if ($metadata instanceof Group && $groupName === $metadata->groupName()) {
127+
return true;
128+
}
129+
}
130+
131+
return false;
102132
}
103133
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\PhpUnit\Tests;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\PhpUnit\ClockMock;
16+
use Symfony\Bridge\PhpUnit\DnsMock;
17+
18+
class SymfonyExtensionWithManualRegister extends TestCase
19+
{
20+
public static function setUpBeforeClass(): void
21+
{
22+
ClockMock::register(self::class);
23+
ClockMock::withClockMock(strtotime('2024-05-20 15:30:00'));
24+
25+
DnsMock::register(self::class);
26+
DnsMock::withMockedHosts([
27+
'example.com' => [
28+
['type' => 'A', 'ip' => '1.2.3.4'],
29+
],
30+
]);
31+
}
32+
33+
public static function tearDownAfterClass(): void
34+
{
35+
ClockMock::withClockMock(false);
36+
DnsMock::withMockedHosts([]);
37+
}
38+
39+
public function testDate()
40+
{
41+
self::assertSame('2024-05-20 15:30:00', date('Y-m-d H:i:s'));
42+
}
43+
44+
public function testGetHostByName()
45+
{
46+
self::assertSame('1.2.3.4', gethostbyname('example.com'));
47+
}
48+
49+
public function testTime()
50+
{
51+
self::assertSame(1716219000, time());
52+
}
53+
54+
public function testDnsGetRecord()
55+
{
56+
self::assertSame([[
57+
'host' => 'example.com',
58+
'class' => 'IN',
59+
'ttl' => 1,
60+
'type' => 'A',
61+
'ip' => '1.2.3.4',
62+
]], dns_get_record('example.com'));
63+
}
64+
}

src/Symfony/Bridge/PhpUnit/Tests/symfonyextension.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ if (!getenv('SYMFONY_PHPUNIT_VERSION') || version_compare(getenv('SYMFONY_PHPUNI
55
--FILE--
66
<?php
77
passthru(\sprintf('NO_COLOR=1 php %s/simple-phpunit.php -c %s/Fixtures/symfonyextension/phpunit-with-extension.xml.dist %s/SymfonyExtension.php', getenv('SYMFONY_SIMPLE_PHPUNIT_BIN_DIR'), __DIR__, __DIR__));
8+
echo PHP_EOL;
9+
passthru(\sprintf('NO_COLOR=1 php %s/simple-phpunit.php -c %s/Fixtures/symfonyextension/phpunit-with-extension.xml.dist %s/SymfonyExtensionWithManualRegister.php', getenv('SYMFONY_SIMPLE_PHPUNIT_BIN_DIR'), __DIR__, __DIR__));
810
--EXPECTF--
911
PHPUnit %s
1012

@@ -17,3 +19,14 @@ Time: %s, Memory: %s
1719

1820
OK, but there were issues!
1921
Tests: 46, Assertions: 46, Deprecations: 1.
22+
23+
PHPUnit %s
24+
25+
Runtime: PHP %s
26+
Configuration: %s/src/Symfony/Bridge/PhpUnit/Tests/Fixtures/symfonyextension/phpunit-with-extension.xml.dist
27+
28+
.... 4 / 4 (100%)
29+
30+
Time: %s, Memory: %s
31+
32+
OK (4 tests, 4 assertions)

0 commit comments

Comments
 (0)