何もしないメソッドのテスト
弊社ではJUnit5でJUnitを書いているのだが、次のような既存メソッドのテストをどうしようか迷った。(ググレカスと言われかねない)
public class HogeCheck{
/**
* Api経由で何かしらの値をチェックし、trueの場合、専用Exceptionを投げる
* @param url
*/
public void hogeCheck(url){
boolean checkResult = new FugaApi(url).check();
if(checkResult){
throw new HogeHugaException();
}
}
}
個人的にvoidはあんまり好みじゃないというか、テストしにくいからできるだけ敬遠している。
返り値を作れるならそうなるようコードReviewでも指摘を入れることがよくある。
しかし今回のコードはレガシーコード。つまりテストのないコード。
ここについてはまずテストを書くことを優先した。
前出のメソッドの正解のテストを以下に記載していく。
プロダクションコード
public class HogeCheck{
/**
* Api経由で何かしらの値をチェックし、trueの場合、専用Exceptionを投げる
* @param url
*/
public void hogeCheck(url){
boolean checkResult = new FugaApi(url).check();
if(checkResult){
throw new HogeHugaException();
}
}
}
テストコード
public class HogeCheckTest{
@DisplayName("APIで取得した結果がtrueの場合、例外が発生")
public void testHogeCheck_exception(){
String errorUrl = "https://xxxx.yyyy";//trueが返ってくるurl
HogeCheck it = new HogeCheck();
assertThrows(HogeHugaException.class, () -> it.hogeCheck(errorUrl));
}
}
Exceptionが発生することのテストは↑のように書くことができる。
FYI
一方、Exceptionが発生しない場合は、assertDoesNotThrowを利用できる。
public class HogeCheckTest{
@DisplayName("APIで取得した結果がfalseの場合、例外が発生しない")
public void testHogeCheck_no_exception(){
String url = "https://xxxx.zzzz";//falesが返ってくるurl
HogeCheck it = new HogeCheck();
assertDoesNotThrow(() -> it.hogeCheck(url));
}
}
記法はassertThrowsと似ているので書きやすいし忘れにくい。
- assertThrowsの第一引数はExceptionのクラスを定義、assertDoesNotThrowはそれがない
- それ以外の記法は差異なし。
最後に
ポイントとしてはreturnがvoidのメソッドで、
条件付きでExceptionを発生させるメソッド(つまり外から見ると何も起きないこともある)場合は前出の記法で分岐網羅が可能である。(Exception発生可否基準で)
一方Exceptionもくそもないreturnがvoidのメソッドの場合(DTOのsetterとか)は、
- 素直にgettterで検証する
- Mockito verifyを使う
などによって、検証は可能である。