2013年10月15日火曜日

最強モックツール JMockit その9 メソッド丸替え

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

現在はモックツール「JMockit」の使い方をご紹介しています。

今回はメソッドの中身の丸ごと差し替えです。

メソッド全体の差し替え

今までご紹介してきたモック機能というのは、『元々のメソッドを実行しないで、仮の値を返す』というものです。

例えば、ログインチェック機能の場合、
本来の機能であれば『ログインIDとパスワードをチェックして、正しい場合はtrue、間違っている場合はfalseを返す』だったとします。
しかし、モック化することによって『いつも固定でtrueにする』とか、そういう感じです。

この場合、元々のメソッドは実行していませんので、DBにアクセスに行っていません。
ただ単に『true』という値が帰ってくるだけです。

このように、『返り値だけあればいい』という状況であれば今までのやり方でOKです。
しかし、そうではなくて、『別の処理をちゃんと実行して欲しい』という場合は、これではダメです。

例えば、以下のような状況です。

  • DBに間違った値が入った時のテストだから、本来の機能はモック化して潰し、代わりに間違った値をインサートさせたい。
  • メール送信機能のテストなんだけど、メール送信処理自体は実際にはメールを送信しなくていいからモック化する。でも、同時に行っている一時ファイル削除処理は行っておく必要がある。

このように、『ダミーの値を返すだけではなくて、違う処理をやりたい』という場合です。
こういう場合は、元々のメソッドをぶっ潰して、違う機能を書いてしまいましょう。

『メール送信後、ファイルを削除する』機能をモック化するというシチュエーションを想定します。
(サンプルなので、printでその処理を行ったという想定とします)

public class MailManager {
 public void sendMail(){
  System.out.println("★メールを送信する。★");
  System.out.println("送信した添付ファイルを削除する。");
 }
}

JUnitは単体テストですが、メール送信はプログラムだけでなくメールサーバも必要とします。
こういう風に違うサーバを必要とする処理のテストは結合テストで行って、単体テストフェーズではモックで済ます、というのは常套手段と言えるでしょう。

しかし、同時に行っている添付ファイル削除処理は実施しなければ都合が悪いということもあるでしょう。
もしくは、『メール送信は成功したけど、ファイル削除は失敗した』という状況を作りたかったりするなど、細かい要望は色々あります。

そういう場合、モックでメソッドを新規作成してしまえば良いのです。

以下がそのやり方です。

@Test
 public void testCreateFile() {
  new MockUp<MailManager>() {
   @Mock
   void sendMail() {
    System.out.println("ファイル削除(差し替え)");
   }
  };
  //メール送信
  MailManager manager = new MailManager();
  manager.sendMail();
 }

JMockitの場合、今回新規登場の『MockUp』というクラスを使うことで実現できます。

使い方も分かりやすいかと。
MockUpクラスの中で同じ名前のメソッドを書いて、@Mockをつければ、それだけで後は自動でモック化されます。

直感的に分かるようによく出来ているライブラリだと感心してしまいます。

終わりに


今回ご紹介したサンプルは、実際のところは回避可能でもあるんですよね。
だって、『メール送信』と『ファイル削除』を別々のメソッドにして、メール送信メソッドだけモック化すれば良いのですから。
しかし、実際の開発だとクラス設計がJUnitのことまで考えられていなくて、こういう作りになっていることもしばしば。
不本意ながらに結構お世話になってしまう機能かもしれません。

もしくは、『ファイル削除失敗』みたいに現実には実現出来ないシチュエーションを作るにも便利です。

代替機能を自分で作る手間はありますが、こんな風に自由に作り込める機能は大変助かりますね。

引き続きJMockitのご紹介をしていきます。

0 件のコメント:

コメントを投稿