#はじめに
初めて記事を書きます。ここ一か月弱、ずっと単体テストを書いていたのでその備忘録。
モック化についてまとめたいと思います。
#####18日担当者の簡単なプロフィール
- 今年からプログラミングのバイトを始めた
- 完全な初心者に毛が生えた程度
よって、この記事は単体テストに困っている初心者向けのものとなっております。
##モック化とは?
まずはここから行きたいと思います。
そもそもモック化とは、単体テストを書くときのハリボテのようなものです。(そう言う風に私はまず習った・・・と思いたい。記憶違いだったらごめんなさい。)
例えば、テストを書いている時にこんな問題があったとします。
- コードが未実装
- そもそも処理が膨大
これをいちいち気にしていたら、大変ですよね?
って言うことで、mock化をしてとりあえずハリボテにしちゃって部品として使えるようにしようぜ!って言う話です。少なくとも私はそう言う風に認識しております。
mock化は便利ですけど、忘れちゃいけないのはverifyです。
これで、mock化をしたのはいいが、きちんと呼び出されているのか・・・!?という問題を解消できます。
きちんと呼び出し検証はやりましょう!(自分にも言い聞かせながら)
##publicメソッドのモック化
全てmock化していい場合はこっち
Smaple Smaple = mock(Smaple.class);
インスタンスだけmock化したい時はこっち
Smaple Smaple = spy(new Smaple());
値を入れていく。
//戻り値がある場合
doRutrn(hoge).when(hoge).method();
when(hogClass.method()).thenReturn();
//戻り値がない場合
doNothing().when(hoge).method();
mock化したら、値の確認を行う。
assertThat(hoge, is(hoge));
//nullの場合
assertThat(hoge, nullValue());
//listの場合
assertThat(list.get(0), is(hoge1));
assertThat(list.get(1), is(hoge1));
:
こんな感じでやっていく。
基本的にmock化したものは全て確認すべき。mock化しただけでは意味がないことに注意。
最後に呼び出し検証を行う。
verify(hoge).method();
//何回呼び出されていたのか検証する場合
verify(hoge, times(num)).method();
##privateメソッドのモック化
privateメソッドであれば、上記のやり方ではできないため、注意。
まずインタンスを作る。
Sample mockInstance= PowerMockito.mock(Sample.class);
//spyのとき
PowerMockito.spy(Sample.class);
次にmock化。
PowerMockito.doReturn(hoge).when(Smaple.class, "sampleMethod");
PowerMockito.doReturn(hoge).when(Smaple.class, "sampleMethod2", hoge, hoge);
//戻り値がない場合
PowerMockito.doNothing().when(Smaple.class, "sampleMethod");
値の確認を行った後、verifyで呼び出し検証を行う。
そのやり方は以下の通り。
verifyPrivate(Sample).invoke("sampleMethod");
verifyPrivate(Sample).invoke("sampleMethod2", hoge, hoge);
##staticメソッドのモック化
インスタンスを作って、実行するまで。
PowerMockito.mockStatic(Smaple.class);
//実行
when(Smaple.method()).thenReturn(hoge);
値の検証をした後、verifyで呼び出し検証を行う。
PowerMockito.verifyStatic();
Sample.method();
##newをモック化する方法
newのmock化は方法が二つある。
####①PowerMockitoを使って行う
//引数がない場合
PowerMockito.whenNew(Sample.class).withNoArguments().thenReturn(hoge);
//引数がある場合
PowerMockito.whenNew(Sample.class).withArguments().thenReturn(hoge);
//戻り値がない場合
doNothing().when(Smaple.class).persist(any(Object));
setされているものがある場合はassertThatで値の確認をすることを忘れないようにする。
####②caputerを使う
caputerの使い方は以下の通り
ArgumentCaptor<Sample> captor = ArgumentCaptor.forClass(Smample.class);
doNothing().when(hoge).persist(captor.capture());
また、次のようにやれば値が取れるようになる。
captor.getValue();
captor.getAllValues();
これを使って、assertThatで検証。
##おわりに
いかがでしたでしょうか?
自分がやっていて困ったところも含めて記事にしております。
これが誰かのお役に立てれば、そんなに嬉しいことはありません。
また、このようなまとめて整理する機会をくださった先輩に謝辞を改めて申し上げます。