getFileName(), "{$dirSeparator}unit{$dirSeparator}" ) === false ) { self::fail( 'This unit test needs to be in "tests/phpunit/unit"!' ); } self::$unitGlobals =& TestSetup::$bootstrapGlobals; foreach ( self::getAllowedGlobalsList() as $global ) { self::$unitGlobals[ $global ] =& $GLOBALS[ $global ]; } // Would be nice if we could simply replace $GLOBALS as a whole, // but un-setting or re-assigning that breaks the reference of this magic // variable. Thus we have to modify it in place. self::$originalGlobals = []; foreach ( $GLOBALS as $key => $_ ) { // Stash current values self::$originalGlobals[$key] =& $GLOBALS[$key]; // Remove globals not part of the snapshot (see bootstrap.php, phpunit.php). if ( $key !== 'GLOBALS' && !array_key_exists( $key, self::$unitGlobals ) ) { unset( $GLOBALS[$key] ); } } // Restore values from the early snapshot // Not by ref because tests must not be able to modify the snapshot. foreach ( self::$unitGlobals as $key => $value ) { $GLOBALS[ $key ] = $value; } } /** * @inheritDoc */ protected function runTest() { try { // Don't let LoggerFactory::getProvider() access globals or other things we don't want. LoggerFactory::registerProvider( ObjectFactory::getObjectFromSpec( [ 'class' => NullSpi::class ] ) ); return parent::runTest(); } catch ( ConfigException $exception ) { throw new Exception( 'Config variables must be mocked, they cannot be accessed directly in tests which extend ' . self::class, $exception->getCode(), $exception ); } } /** * The annotation causes this to be called immediately after tearDown() * @after */ final protected function mediaWikiTearDown(): void { // Quick reset between tests foreach ( $GLOBALS as $key => $_ ) { if ( $key !== 'GLOBALS' && !array_key_exists( $key, self::$unitGlobals ) ) { unset( $GLOBALS[$key] ); } } foreach ( self::$unitGlobals as $key => $value ) { $GLOBALS[ $key ] = $value; } } /** * The annotation causes this to be called immediately after tearDownAfterClass() * @afterClass */ final public static function mediaWikiTearDownAfterClass(): void { // Remove globals created by the test foreach ( $GLOBALS as $key => $_ ) { if ( $key !== 'GLOBALS' && !array_key_exists( $key, self::$originalGlobals ) ) { unset( $GLOBALS[$key] ); } } // Restore values (including reference!) foreach ( self::$originalGlobals as $key => &$value ) { $GLOBALS[ $key ] =& $value; } } }