• 2019年5月27日月曜日
アリスト戦記
アリスト戦記 https://blog.aristo-solutions.net/2019/05/junit5assertthrows.html

JUnit5で例外の発生を検知「assertThrows」

Java開発をやってて泣けてくるのは、Javaには「例外」ってものがあるんだぜ。
if文があって、「Trueの方が正常」「Falseの異常」じゃないんだよ。

True/Falseの考え方はパラメータ的に正しいかどうかでしょ?
それとは別にネットワーク断とか予期せぬトラブルが起きることがあるじゃないか。それが異常系であり、Exceptionだ。

「処理の結果がfalseであること」と「異常」がゴッチャになってるヤツがいるから注意。

今回はJUnit5で異常系であるExceptionをチェックする方法の解説だ。

assertThrows

まずは「例外が発生すること」をチェックする。

例外発生する

サンプルとして、まず以下のように例外発生ソースがあるとするでしょ。

public void sampleThrow() throws NullPointerException {

   throw new NullPointerException("テスト用のexeptionです。");

}

検証

メソッド「sampleThrow」でエラーが発生することを確認する処理はこちら。

@Test
public void test1() {

   assertThrows(NullPointerException.class, () -> sampleThrow());

}

メソッドを実行し、そのクラスが「NullPointerException.class」であることを確認する、という処理だ。
「() -> sampleThrow()」とあるけど、これがラムダ式だ。

JUnit4から進化したJUnit5では、ラムダ式の取込が行われている。

ラムダ式のメリット

実を言うと、僕は余りラムダ式が好きじゃないっていうか、あんまり使わないんだよね。
確かにラムダ式を使うことでソースを省略することも出来るんだが、そもそもソースの省略は必ずしも良いことであろうか?

僕の持論としては、Javaってのは多少ソースが冗長であろうとも、あらゆることをキッチリ宣言、定義して、固く作っていく思想である所にメリットがある。
冗長でもラムダ式を使わず書いた方が誤読が無いし、初心者にも分かり易いんだ。

まあ、同じJavaでもスピード重視のAndroid開発とかなら思想が違うのかもしれんが、僕は大規模Java開発に適合した技術者であるから、書き易さよりも固さ、保守性の方を重視する性格だ。

しかし、何事にも例外はある。JUnitだ。
JUnitはラムダ式と相性が良いと僕は考えている。

と言うのも、あらゆる可能性を考慮しなければならない本系開発とは違い、JUnitってのは型にハマった同じことの繰り返しでしょ?
「読解」とかそんなものは無いんだ。読むまでも無く意味は分かっている。

っていうか、JUnitってメタ的な挙動をするから、「仕組みは分からないが、とにかくJUnitはこう書けば動くんだ!!」くらいの認識で書くものじゃないか。

であれば、単純にSTEP数が小さい方が正義!!
JUnitはラムダ式と相性が良い。

僕の古いJavaエンジニアは最近の機能であるラムダ式とかは敬遠しがちであるが、そこは自戒して取り込んでいかなければならんな。

assertDoesNotThrow

逆に、例外にならないことをチェックする為の機能が「assertDoesNotThrow」だ。
これは直感で分かるだろう。
こういうことだ。

public void sampleOK() throws NullPointerException {

   //例外が起きない。

}

@Test
public void test2() {

   assertDoesNotThrow(() -> sampleOK());

}

例外のメッセージまでチェックしたい

上記のサンプルは例外の型だけチェックするものであるが、「例外」の中に含まれれるメッセージなどの属性まで詳細にチェックしたいという場合、もあるのかな?

そこまでしっかりやっているプロジェクトは見たこと無いが(;^_^)
技術的には可能である。

こうやって書く。

@Test
void exceptionTesting() {

   Throwable exception = assertThrows(NullPointerException.class, () -> sampleThrow());

   assertEquals("テスト用のexeptionです。", exception.getMessage());

}

assertThrowsは例外クラスをレスポンスに返しているから、それを受け取って後は好きにするって書き方だ。

まあ、JUnit内でTryCatchを書くのと変わらんと思うが、せっかくなのでJUnitの作法に従った方が綺麗だろうな。

0 件のコメント:

コメントを投稿