PHP
PHPUnit

[PHPUnit]あるクラスの指定のメソッドのみをmockするやり方


概要

PHPUnitのテストをやっているとやっぱりmockを使えると便利ですよね!

ということでmockを使ったテストのやり方についてです


さっそくやってみる

まずこんな感じのテストしたいクラスがあることにしましょう。


target.php

class Target{

private $otherClass;

public function construct(OtherClass $otherClass)
{
$this->otherClass = $otherClass;
}

public function start()
{
//ここで色々な処理があるとする
try{
$result = $this->next();
return $result;
}catch(Exception $e){
return false;
}
}

public function next()
{
//なんらかの処理をしてその結果を返す
$processResult = $this->process();
if($processResult === true){
return true;
}else{
return false;
}
}
}


コンストラクタのインジェクションで別のクラスが注入されてて、start関数がnext関数を呼んでいるとしましょう。

start関数は色々な処理をした後にnext関数を呼んでいて、next関数はなんらかの処理をしたあとその結果を返します。

このときに、next関数だけをmockにしてstart関数はそのままの状態でテストしたかったのでこう書きました!


test.php

class Test{

public function test001()
{
//makePartialを使うことでshouldReceiveを設定したクラスのみをモックにすることが可能。mockの第二引数はコンストラクタ
$targetClassMock = Mockery::mock(Target::class, [OtherClass::class])->makePartial();
//next関数が呼ばれたらtrueを返すようにモックを設定する
$targetClassMock->shouldReceive('next')->andReturn(false);
//start関数をコール
$ret = $targetClassMock->start();
//Trueであることを確認
$this->assertTrue($ret);
}
}


また、next関数で例外が発生したときに、それがちゃんとキャッチされてreturn falseを返せるかも確認したいです。

そういうときはこう書きます。


test.php

class Test{

public function test002()
{
//さっきと同じ
$targetClassMock = Mockery::mock(Target::class, [OtherClass::class])->makePartial();
//next関数が呼ばれたらエラーが発生するようにモックを設定する
$targetClassMock->shouldReceive('next')->andThrow(new Exception('test002だよ');
//さっきと同じ
$ret = $targetClassMock->start();
//falseであることを確認
$this->assertFalse($ret);
}
}


まだまだ他にも奥が深そうですが、自分がやりたいことは一旦できたので共有ここまで。

もっと色々と手を出してみたいですね!