EasyMockサポート
EasyMockはモックを利用したテストのためのフレームワークです.モックの振る舞いを設定するのにメソッド名などを文字列で指定するのではなく,インタフェースのメソッド呼び出しで指定することができるため,タイプミスを防げる・エディタの入力補完を利用できる・リファクタリングに追従しやすいなどのメリットがあります.
Seasar2のEasyMockサポートを使うとEasyMockを利用するための定型的なコードの記述を減少することができるため,モックを使ったテストがより簡単になります.
- Seasar2ではEasyMock2.4およびEasyMock Class Extension2.4をサポートしています.
- EasyMock単体でも利用できます.
- EasyMock Class Extensionを使用するにはCGLIBも必要です.
- EasyMock2.4はJava5で導入されたGenericsを使用しているため,J2SE1.4では利用できません.
- Seasar2のEasyMockサポートを利用するにはS2-Tigerが必要です.
EasyMockを使ったテストの流れを以下に示します.
- モックを作成する
- モックの振る舞いを記録する (record)
- モックとのインタラクションを再現する (replay)
- モックとのインタラクションを検証する (verify)
モックとインタラクションする「replay」モードのコードが本来のテストコードになります.
Seasar2のEasyMockサポートもこの流れに沿ったテストを支援します.
Seasar2のEasyMockサポートはJUnit3とJUnit4の両方をサポートします.
JUnit3
JUnit3でEasyMockを使ったテストを行うために,次の二つの抽象クラスが提供されています.
org.seasar.framework.unit.EasyMockTestCase
junit.framework.TestCase の派生クラスで,S2コンテナを利用しない場合に使用します.
org.seasar.framework.unit.S2TigerTestCase
org.seasar.framework.unit.S2TestCase の派生クラスで,S2コンテナを利用する場合に使用します.
public class HogeTest extends S2TigerTestCase {
・・・
}
JUnit4
JUnit4でEasyMockを使ったテストを行うには,S2JUnit4のRunnerを使用します.
@RunWith(Seasar2.class)
public class HogeTest {
・・・
}
モックを作成するにはテストクラスのフィールドに@EasyMock アノテーションを指定します.
public class HogeTest extends S2TigerTestCase {
@EasyMock
private Foo foo;
・・・
}
@EasyMockアノテーションが付けられたフィールドの型からモックが作成され,フィールドに設定されます.
モックの種類を指定することもできます.それには@EasyMock アノテーションのvalue 要素で列挙型EasyMockType の定数を指定します.
public class HogeTest extends S2TigerTestCase {
@EasyMock(EasyMockType.STRICT)
private Foo foo;
・・・
}
列挙型EasyMockType には以下の定数があります.
DEFAULT
- デフォルトモードのモックを作成します.
デフォルトモードのモックは指定されていないメソッドが呼び出されると例外をスローしますが,メソッドの呼び出し順は無視します.
STRICT
- Strictモードのモックを作成します.
Strictモードのモックは指定されていないメソッドが呼び出されると例外をスローします.指定されたメソッドであっても,指定された通りの順でメソッドが呼び出されないと例外をスローします.
NICE
- Niceモードのモックを作成します.Niceモードのモックは指定されていないメソッド呼び出しが行われても例外をスローしません.
S2TigerTestCase のサブクラスでは,作成されたモックをS2コンテナに登録することができます.それには@EasyMockアノテーションのregister 要素でtrue を指定します.
public class HogeTest extends S2TigerTestCase {
@EasyMock(register=true)
private Foo foo;
・・・
}
モックのコンポーネント名はフィールド名となります.
モックの登録はS2コンテナの初期化前に行われるため,登録されたモックは他のコンポーネントにDIされる対象となります.モックに対するDIは行われません.
JUnit3では,@EasyMock アノテーションを使わず,setUp() メソッドまたはsetUpXxx() メソッド (S2TigerTestCase のサブクラスのみ) の中で明示的にモックを作成することもできます.それには以下のメソッドを使用します.
T createMock(Class<T>)
T createStrictMock(Class<T>)
T createNiceMock(Class<T>)
public class HogeTest extends S2TigerTestCase {
private Foo foo;
protected void setUp() throws Exception {
super.setUp();
foo = createMock(Foo.class);
}
・・・
}
モックの振る舞いを記録するには,"record"メソッドを使用します.
JUnit3
"record"メソッドはテストメソッドの接頭辞"test"を"record"にした名前を持つpublic なインスタンスメソッドです.
public class HogeTest extends S2TigerTestCase {
public void recordXxx() throws Exception {
・・・
}
public void testXxx() throws Exception {
・・・
}
}
testXxx() メソッドの実行前に,対応するrecordXxx() メソッドが実行されます.テストメソッドがtest() の場合は対応する"record"メソッドは実行されません.
JUnit4
"record"メソッドはテストメソッドに接頭辞"record"をつけた名前を持つpublic なインスタンスメソッドです.
@RunWith(Seasar.class)
public class HogeTest {
public void recordXxx() throws Exception {
・・・
}
public void xxx() throws Exception {
・・・
}
}
xxx() メソッドの実行前に,対応するrecordXxx() メソッドが実行されます.
JUnit3とJUnit4共通
"record"メソッド内ではEasyMockの機能を使用してモックの振る舞いを記録します.
public void recordXxx() throws Exception {
expect(foo.someMethod(100)).andReturn(200);
}
expect メソッドはorg.easymock.EasyMock のstaticメソッドです。この例ではstatic import機能を利用して呼び出しています.
モックとのインタラクションを再現するには通常のテストメソッドを使用します.
作成済みのモックは,テストメソッドの実行前に"replay"モードに設定されます.
public void testXxx() throws Exception {
assertEquals(200, foo.someMethod(100));
}
テストメソッドの実行が正常に終了すると自動的にモックとのインタラクションが検証されます.
|