社内se × プログラマ × ビッグデータ

プログラミングなどITに興味があります。

Mockito のチュートリアル記事を読んだ感想

これです。
www.discoversdk.com

実際のところ、Mockito って Mavenリポジトリを見ても、12/31/2014以降は新しいバージョンが出ていないくらい完成された?フレームワークなのかもしれない。
ただ、この記事は 5/25/2017 に更新されたのもので、個人的にそんなに詳しくないので、読んでみました。

Mockito とは?

Javaオープンソースフレームワークで、モックを簡単に作れるよ。
モックというのは、ユニットテストで使えるダミーの機能(実装はされていない)みたいなもの。
※この記事には、最新バージョンが Mockito release is version 1.9.5 と紹介されているけど、1.10.19 までは出ているはず

Mavenを使用してのクラスパスの追加

記事内では mockito と junit と assertj を追加していました。
assertj は使ったことがないです。

Mockito と JUnit

簡単に試せれば何でも良いので、以下の2つのクラスを定義しました。
1) 1 - 100 内の数字をランダムに生成するクラス。NumberGenerator.class
2) 2 つの数字の平均を求めるクラス。AverageCalculator.class

正直、プログラミングの練習のために、適当なクラスを考えるのは苦手です。

Mockito を使うためには

1. テストクラスに @RunWith のアノテーションをつける。

2. テストフィールドに @Mock もしくは @Spy のアノテーションをつける。
要するに、モックをつくりたいオブジェクトはここで定義する。

3. モックを注入するクラスに、@InjectMocks のアノテーションをつける。
要するに、テスト対象のクラスということになると思います。

アノテーションをつけることはわかるのですが、それによって内部的にどういう動きをするようになるのかが知りたいところです。
プログラミングしていてよく感じることですが、なぜこの一行を加えるだけで、全く違う動きになるのか?というところは、ソースコードが公開されているライブラリであれば、調べようと思えば調べられることなんですけどね。
知らなくても何とかなる部分でも、興味があればトコトン調べれば良いだろうし、そこまで無いのであれば、もっと興味のある方に時間をかけた方が良い部分だとは思います。

テストコード

以下のようになりました。

@RunWith(MockitoJUnitRunner.class)
public class AverageCalculatorTest {
	
@Mock
NumberGenerator numberGeneratorMock;
	
@InjectMocks
AverageCalculator averageCalculatorMock;

@Test
public void test() {
    // given
    given(numberGeneratorMock.generateNumber()).willReturn(50);
		
    // when
    Integer average = averageCalculatorMock.getAverage();
		
    // then
    then(average).isEqualTo(50);
}
}

普通に JUnit を実行させると、テスト結果が返ってきます。
おおまかな流れは以下のようになっていると思います。

1. NumberGenerator のモックが作られる
2. AverageCalculator のモックに NumberGenerator のモックが注入される
3. generateNumber() の戻り値が 50 で固定される
4. よって getAverage() の結果は 50 となる

用語

Dummy: ビジネスロジックに全く関わりのないコードのためのオブジェクト。
例えば、パラメーターを関数に渡すだけとか。
> ダミーと呼ぶのは、聞いたことがないですね。

Fake: 本番環境では使用しないオブジェクト。
例えば、メモリ上で動作する H2 データベースとか。
> これも意識して、フェイクと呼んだりしていない。

Stub: テスト中において、実行結果を予め定義してあるオブジェクト。
> スタブはよく耳にすると思いますが、モックとの違いがよく議論されていますね。

Mock: テスト中において、実行結果を予め定義してあるオブジェクトで、各実行の期待値が記録(保持)されている。
> スタブとの違いは、期待値を持っているかどうか?だけ。

Spy: スタブと似ているが、更にどのように実行されたか?が記録されている。
> スパイとか呼んだことありません。

普段は、スタブとモックを使い分けることなんかしていなくて、「テスト時に使うダミー的なコードはすべてモック」(上に書いたやつ全部まとめて)と呼んでいる気がします。

Mockito と TestNG

TestNG は、単体テスト、機能テスト、総合テストなどすべてのカテゴリを網羅するテストフレームワーク(らしい)。
最初、TestNG って、「テスト失敗」のことだと思ってました。
NG って、NextGeneration から取っているみたいですが、英語圏の人からするとややこしくないのだろうか。
JUnitに似ているけど、拡張版ではないらしい。
ただ、JUnit4 の方が新しいフレームワークなので、今や NextGeneration とは呼びにくいでしょうけど。

まとめ

Mockito 初心者によって、分かりやすい内容だったと思います。
本当に単純なコードを一つ書いただけですが、最初のチュートリアルはこのくらいが良いのかもしれません。

用語については、あまり考えて使い分けていないことを改めて感じさせられました。
この辺は開発現場にかなり依存してしまっている気がします。

TestNG は今度試してみたいですが、コスト的に JUnit4 から移行するかどうかは分からないです。
歴史のあるフレームワークなのに、まだまだ知らないこと多いです。(耳にした覚えがなかったです)
特に海外では評価が高いフレームワークなので、海外の記事を呼んでいるとこういった情報が入ってくるかもしれませんね。
あと、assertj は面白そうです。