この記事ではLaravelを利用している場合のユニットテストで、Monologの出力結果をテストする方法を紹介します。
テストする対象のクラスは以下のような感じです。
class Log {
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function exec(): void
{
$this->logger->info('sample log');
}
}
このlogger->info
で適切文言が出力されていることを確認するユニットテストを書きます。
class LoggingTest extends TestCase {
private $log;
public function setUp(): void
{
parent::setUp();
config([
'logging' => [
'channels' => [
'test' => [
'driver' => 'custom',
'via' => function () {
$handler = new TestHandler();
return new Logger('test', [$handler]);
},
],
],
],
]);
$this->log = new Log($this->app->make(LoggerInterface::class));
}
/**
* @test
* /
public function logging()
{
$this->log->exec();
$records = $this->app->make(LoggerInterface::class)
->getHandlers()[0]
->getRecords();
$this->assertCount(1, $records);
$this->assertEquals(
'sample log',
$records[0]['message']
);
}
}
phpunit.xmlに以下を追加
<php>
<env name="LOG_CHANNEL" value="test"/>
</php>
また、Laravel5.6以前であればsetUp
にconfig
ではなく、以下のコードを挿入でも行けるみたいです(検証してません)
$this->app->configureMonologUsing(function ($monolog) {
$monolog->pushHandler(new \Monolog\Handler\TestHandler());
});
解説
$records = $this->app->make(LoggerInterface::class)
->getHandlers()[0]
->getRecords();
このgetHandlers
では登録されているHandlerが配列で取得でき、今回はchannels.testは一つのHandlerしか登録していないので配列の先頭でTestHandler
が取得できます。
TestHandler
にはgetRecords
メソッドからlogとして出力されたレコードが取得できます。
これによってテスト時に実行されたログと比較して意図した出力になっているかどうかを確認することがきでます。