From a684a2a66ba31daa6888de6170cccadfe11dfe43 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gerg=C5=91=20Tisza?= Date: Sun, 7 Feb 2016 08:12:10 +0000 Subject: [PATCH] Add MediaWikiTestCase convenience method for mocking a logger Change-Id: I2f96eddf9f010333ab515c980f4158dce410a13a --- tests/phpunit/MediaWikiTestCase.php | 66 +++++++++++++++++++ tests/phpunit/tests/MediaWikiTestCaseTest.php | 34 ++++++++++ 2 files changed, 100 insertions(+) diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php index f69e342ad4..2e1e2706b6 100644 --- a/tests/phpunit/MediaWikiTestCase.php +++ b/tests/phpunit/MediaWikiTestCase.php @@ -1,4 +1,8 @@ mwGlobals = array(); + $this->restoreLoggers(); RequestContext::resetMain(); MediaHandler::resetCache(); if ( session_id() !== '' ) { @@ -404,6 +415,61 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->setMwGlobals( $name, $merged ); } + /** + * Sets the logger for a specified channel, for the duration of the test. + * @since 1.27 + * @param string $channel + * @param LoggerInterface $logger + */ + protected function setLogger( $channel, LoggerInterface $logger ) { + $provider = LoggerFactory::getProvider(); + $wrappedProvider = TestingAccessWrapper::newFromObject( $provider ); + $singletons = $wrappedProvider->singletons; + if ( $provider instanceof MonologSpi ) { + if ( !isset( $this->loggers[$channel] ) ) { + $this->loggers[$channel] = isset( $singletons['loggers'][$channel] ) + ? $singletons['loggers'][$channel] : null; + } + $singletons['loggers'][$channel] = $logger; + } elseif ( $provider instanceof LegacySpi ) { + if ( !isset( $this->loggers[$channel] ) ) { + $this->loggers[$channel] = isset( $singletons[$channel] ) ? $singletons[$channel] : null; + } + $singletons[$channel] = $logger; + } else { + throw new LogicException( __METHOD__ . ': setting a logger for ' . get_class( $provider ) + . ' is not implemented' ); + } + $wrappedProvider->singletons = $singletons; + } + + /** + * Restores loggers replaced by setLogger(). + * @since 1.27 + */ + private function restoreLoggers() { + $provider = LoggerFactory::getProvider(); + $wrappedProvider = TestingAccessWrapper::newFromObject( $provider ); + $singletons = $wrappedProvider->singletons; + foreach ( $this->loggers as $channel => $logger ) { + if ( $provider instanceof MonologSpi ) { + if ( $logger === null ) { + unset( $singletons['loggers'][$channel] ); + } else { + $singletons['loggers'][$channel] = $logger; + } + } elseif ( $provider instanceof LegacySpi ) { + if ( $logger === null ) { + unset( $singletons[$channel] ); + } else { + $singletons[$channel] = $logger; + } + } + } + $wrappedProvider->singletons = $singletons; + $this->loggers = array(); + } + /** * @return string * @since 1.18 diff --git a/tests/phpunit/tests/MediaWikiTestCaseTest.php b/tests/phpunit/tests/MediaWikiTestCaseTest.php index 8887499797..33611665dc 100644 --- a/tests/phpunit/tests/MediaWikiTestCaseTest.php +++ b/tests/phpunit/tests/MediaWikiTestCaseTest.php @@ -1,4 +1,5 @@ stashMwGlobals( self::GLOBAL_KEY_NONEXISTING ); } + /** + * @covers MediaWikiTestCase::setLogger + * @covers MediaWikiTestCase::restoreLogger + */ + public function testLoggersAreRestoredOnTearDown() { + // replacing an existing logger + $logger1 = LoggerFactory::getInstance( 'foo' ); + $this->setLogger( 'foo', $this->getMock( '\Psr\Log\LoggerInterface' ) ); + $logger2 = LoggerFactory::getInstance( 'foo' ); + $this->tearDown(); + $logger3 = LoggerFactory::getInstance( 'foo' ); + + $this->assertSame( $logger1, $logger3 ); + $this->assertNotSame( $logger1, $logger2 ); + + // replacing a non-existing logger + $this->setLogger( 'bar', $this->getMock( '\Psr\Log\LoggerInterface' ) ); + $logger1 = LoggerFactory::getInstance( 'bar' ); + $this->tearDown(); + $logger2 = LoggerFactory::getInstance( 'bar' ); + + $this->assertNotSame( $logger1, $logger2 ); + $this->assertInstanceOf( '\Psr\Log\LoggerInterface', $logger2 ); + + // replacing same logger twice + $logger1 = LoggerFactory::getInstance( 'baz' ); + $this->setLogger( 'baz', $this->getMock( '\Psr\Log\LoggerInterface' ) ); + $this->setLogger( 'baz', $this->getMock( '\Psr\Log\LoggerInterface' ) ); + $this->tearDown(); + $logger2 = LoggerFactory::getInstance( 'baz' ); + + $this->assertSame( $logger1, $logger2 ); + } } -- 2.20.1