jMockAdvertisementjMockとは
モックオブジェクトを利用してJavaコードのテストを行うためのライブラリ。
特徴
モックとスタブ
スタブとモックは本質的には同じ(擬似的なオブジェクト)だが、戦略(状態中心 or 相互作用中心)が異なる。また、モックオブジェクトはスタブを包括していると捉えることもできる。
わかりやすいドキュメント。 Martin FowlerによるMocks Aren't Stubs(和訳) モックオブジェクトを利用したテスト
階層分離設計では、隣り合っている層への依存関係が発生するため、切り離してテストを実行しなければならない。
![]() 図1:サンプルクラス図 上記の図ではサービス層とデータベースアクセス層が切り分けられているが、サービス層の単体テストを行うときに実際の実装クラスを利用することができない(実際のデータベースにアクセスしてしまうため。) そこで、データベースアクセス層のクラスをモックオブジェクトに置き換えてテストを実行することで、層を切り分けたテストを実施することができる。 モックオブジェクトのテストにjMockを利用する理由
あるクラスに対してテストを実行する場合、そのクラスから依存しているクラスのモックオブジェクトを用意することになる。
ユーザインタフェース層のテストを行う場合、サービス層のモックオブジェクトが必要になり、サービス層のテストを行う場合、上記のようにデータベースアクセス層のモックオブジェクトが必要となる。 要するに、ほとんどのクラスに対してモックオブジェクトを作成しなくてはいけないのだが、これを手動で作成するのは効率が悪すぎる。また、各モックに対してのメンテナンスの必要も発生してしまう。 jMockは動的にモックオブジェクトの生成を行う(動的Proxy)ので、開発者がモックオブジェクトを実装する手間をまるごと省くことができる。 入手
オフィシャルサイトより。
サンプルコード(QuickStart)
上記サンプルクラス図を実装。
HumanDao.java
public interface HumanDao {
public void select();
public void update(Object dto);
}
HumanLogic.java
public class HumanLogic {
private HumanDao humanDao;
public HumanDao getHumanDao() {
return humanDao;
}
public void setHumanDao(HumanDao humanDao) {
this.humanDao = humanDao;
}
public void createHuman(){
humanDao.select();
// 省略
humanDao.update(new Object());
}
}
jMockを使った単体テストコードHumanLogicTest.java
import org.jmock.Mock;
import org.jmock.MockObjectTestCase;
public class HumanLogicTest extends MockObjectTestCase {
public void testCreateHuman() throws Exception{
Mock mock = mock(HumanDao.class);
mock.expects(once()).method("select").withNoArguments();
mock.expects(once()).method("update").withAnyArguments();
HumanLogic humanLogic = new HumanLogic();
humanLogic.setHumanDao((HumanDao)mock.proxy());
humanLogic.createHuman();
}
}
テストメソッドの最初の行でHumanDaoのモックオブジェクトを作成している。続いてモックオブジェクトに対して想定を設定している。サンプルの場合、HumanLogicクラスの中ではHumanDaoクラスのselectとupdateが1回づつ実行されているので、モックオブジェクトに対して想定として設定している。 mock.expectsの引数InvocationMatcher
メソッドに渡す引数の設定
上記コードではmock()メソッドを利用してモックオブジェクトを生成している。この場合、テストコードの最後で内部的に想定のテストが実行される。 これとは別の方法で、newを利用してモックオブジェクトを生成することもできる。 Mock mock = new Mock(HumanDao.class);この方法でモックオブジェクトを生成した場合、コード内で明示的にverifyメソッド呼び出しを記述する必要がある。 mock.verify(); リンク
|