Is it possible to remove final declaration
huangdijia opened this issue · comments
Deeka Wong commented
phpunit/src/Framework/TestCase.php
Lines 441 to 626 in 654b6c6
final public function runBare(): void | |
{ | |
$emitter = Event\Facade::emitter(); | |
error_clear_last(); | |
clearstatcache(); | |
$emitter->testPreparationStarted( | |
$this->valueObjectForEvents(), | |
); | |
$this->snapshotGlobalState(); | |
$this->snapshotGlobalErrorExceptionHandlers(); | |
$this->startOutputBuffering(); | |
$hookMethods = (new HookMethods)->hookMethods(static::class); | |
$hasMetRequirements = false; | |
$this->numberOfAssertionsPerformed = 0; | |
$currentWorkingDirectory = getcwd(); | |
try { | |
$this->checkRequirements(); | |
$hasMetRequirements = true; | |
if ($this->inIsolation) { | |
$this->invokeBeforeClassHookMethods($hookMethods, $emitter); | |
} | |
if (method_exists(static::class, $this->methodName) && | |
MetadataRegistry::parser()->forClassAndMethod(static::class, $this->methodName)->isDoesNotPerformAssertions()->isNotEmpty()) { | |
$this->doesNotPerformAssertions = true; | |
} | |
$this->invokeBeforeTestHookMethods($hookMethods, $emitter); | |
$this->invokePreConditionHookMethods($hookMethods, $emitter); | |
$emitter->testPrepared( | |
$this->valueObjectForEvents(), | |
); | |
$this->wasPrepared = true; | |
$this->testResult = $this->runTest(); | |
$this->verifyDeprecationExpectations(); | |
$this->verifyMockObjects(); | |
$this->invokePostConditionHookMethods($hookMethods, $emitter); | |
$this->status = TestStatus::success(); | |
} catch (IncompleteTest $e) { | |
$this->status = TestStatus::incomplete($e->getMessage()); | |
$emitter->testMarkedAsIncomplete( | |
$this->valueObjectForEvents(), | |
Event\Code\ThrowableBuilder::from($e), | |
); | |
} catch (SkippedTest $e) { | |
$this->status = TestStatus::skipped($e->getMessage()); | |
$emitter->testSkipped( | |
$this->valueObjectForEvents(), | |
$e->getMessage(), | |
); | |
} catch (AssertionError|AssertionFailedError $e) { | |
if (!$this->wasPrepared) { | |
$this->wasPrepared = true; | |
$emitter->testPreparationFailed( | |
$this->valueObjectForEvents(), | |
); | |
} | |
$this->status = TestStatus::failure($e->getMessage()); | |
$emitter->testFailed( | |
$this->valueObjectForEvents(), | |
Event\Code\ThrowableBuilder::from($e), | |
Event\Code\ComparisonFailureBuilder::from($e), | |
); | |
} catch (TimeoutException $e) { | |
$this->status = TestStatus::risky($e->getMessage()); | |
} catch (Throwable $_e) { | |
if ($this->isRegisteredFailure($_e)) { | |
$this->status = TestStatus::failure($_e->getMessage()); | |
$emitter->testFailed( | |
$this->valueObjectForEvents(), | |
Event\Code\ThrowableBuilder::from($_e), | |
null, | |
); | |
} else { | |
$e = $this->transformException($_e); | |
$this->status = TestStatus::error($e->getMessage()); | |
$emitter->testErrored( | |
$this->valueObjectForEvents(), | |
Event\Code\ThrowableBuilder::from($e), | |
); | |
} | |
} | |
$outputBufferingStopped = false; | |
if (!isset($e) && | |
$this->hasExpectationOnOutput() && | |
$this->stopOutputBuffering()) { | |
$outputBufferingStopped = true; | |
$this->performAssertionsOnOutput(); | |
} | |
if ($this->status->isSuccess()) { | |
$emitter->testPassed( | |
$this->valueObjectForEvents(), | |
); | |
if (!$this->usesDataProvider()) { | |
PassedTests::instance()->testMethodPassed( | |
$this->valueObjectForEvents(), | |
$this->testResult, | |
); | |
} | |
} | |
try { | |
$this->mockObjects = []; | |
} catch (Throwable $t) { | |
Event\Facade::emitter()->testErrored( | |
$this->valueObjectForEvents(), | |
Event\Code\ThrowableBuilder::from($t), | |
); | |
} | |
// Tear down the fixture. An exception raised in tearDown() will be | |
// caught and passed on when no exception was raised before. | |
try { | |
if ($hasMetRequirements) { | |
$this->invokeAfterTestHookMethods($hookMethods, $emitter); | |
if ($this->inIsolation) { | |
$this->invokeAfterClassHookMethods($hookMethods, $emitter); | |
} | |
} | |
} catch (AssertionError|AssertionFailedError $e) { | |
$this->status = TestStatus::failure($e->getMessage()); | |
$emitter->testFailed( | |
$this->valueObjectForEvents(), | |
Event\Code\ThrowableBuilder::from($e), | |
Event\Code\ComparisonFailureBuilder::from($e), | |
); | |
} catch (Throwable $exceptionRaisedDuringTearDown) { | |
if (!isset($e)) { | |
$this->status = TestStatus::error($exceptionRaisedDuringTearDown->getMessage()); | |
$e = $exceptionRaisedDuringTearDown; | |
$emitter->testErrored( | |
$this->valueObjectForEvents(), | |
Event\Code\ThrowableBuilder::from($exceptionRaisedDuringTearDown), | |
); | |
} | |
} | |
if (!$outputBufferingStopped) { | |
$this->stopOutputBuffering(); | |
} | |
clearstatcache(); | |
if ($currentWorkingDirectory !== getcwd()) { | |
chdir($currentWorkingDirectory); | |
} | |
$this->restoreGlobalErrorExceptionHandlers(); | |
$this->restoreGlobalState(); | |
$this->unregisterCustomComparators(); | |
$this->cleanupIniSettings(); | |
$this->cleanupLocaleSettings(); | |
libxml_clear_errors(); | |
$this->testValueObjectForEvents = null; | |
if (isset($e)) { | |
$this->onNotSuccessfulTest($e); | |
} | |
} |
I want to override the runBare method in a subclass, runs in swoole croutine, for example:
public function runBare(): void
{
$exception = null;
\Swoole\Coroutine\run(function () use (&$exception) {
try {
parent::runBare();
} catch (Throwable $e) {
$exception = $e;
} finally {
// do something after run
\Swoole\Timer::clearAll();
\Hyperf\Coordinator\CoordinatorManager::until(\Hyperf\Coordinator\Constants::WORKER_EXIT)->resume();
}
});
if ($exception) {
throw $exception;
}
}
needs the change in phpunit 10.x and 11.x .
Hope to get your reply, Thanks!
Sebastian Bergmann commented
Sorry, but the answer is no.
Deeka Wong commented
Sorry, but the answer is no.
Can you explain the reason for rejection?
The reason why I put forward this requirement is that I hope setUp/tearDown and testCase can run in the same environment.