背景
弊社ではプロジェクトによってアラートをSlackに通知する運用をしているのですが、自動テストを流すと異常系のテストでSlackに通知が飛んでしまっていたので、これを通知しないようにしたかった。
getMockBuilderで...
PHPで開発を行っているプロジェクトなのでPHPUnitを使用しており、getMockBuilderとかcreateMockとかすればできるだろうと考えていました。
Slackの通知は以下のように行っていました。
<?php
class CheckShimasu
{
public function noticeShimasu()
{
$kakukaku = 'かくかく';
$shikazika = 'しかじか';
$kakukakushikazika = $kakukaku . $shikazika;
$slack = new SlackNoClass($kakukakushikazika);
$slack->anochannelnitsuchi();
}
}
なのでgetMockBuilderでこのSlackNoClassをモックにして、テスト対象であるcheckShimasuのnoticeShimasuメソッドをテストしようと思い、以下のように書いてみました。
// slackが1回通知されることのテスト
public function test()
{
$mock = getMockBuilder(SlackNoClass::class)
->setMethods(['anochannelnitsuchi'])
->getMock();
$mock->expects($this->exactly(1))
->method('anochannelnitsuchi');
$sut = new CheckShimasu();
$sut->noticeShimasu();
$this->assertTrue(true);
}
しかしこれではSlackNoClassはモックにされず、Slackに通知が飛んでしまっていました。
どうやらgetMockBuilderやcreateMockでは、テスト対象のクラスでインスタンス化されるクラスまではモックにできないようでした。
そうですか、できないんですね...
いろいろ調べていたところ、getMockBuilderやcreateMockでもできるよというような内容の記事もいくつかを見つけることができましたが、どうにもうまいことモックすることができず...
最終的にはPHPのモッキングフレームワークであるMockeryを入れて、下記のようにSlackNoClassを「'overload'」とすることでSlackの通知を止めることができました。
// slackが1回通知されることのテスト
public function test()
{
Mockery::mock('overload:SlackNoClass')->shouldReceive('anochannelnitsuchi')
->times(1);
$sut = new CheckShimasu();
$sut->noticeShimasu();
$this->assertTrue(true);
Mockery::close();
}
staticの関数のテストでも簡単にできたりもするようですし、他の外部APIを使用しているところなどもあるので、いろいろ調べながら使っていきたいですね。
以上