| # EasyMockサポート ## 目次 概要 前提条件 EasyMockを使ったテストの流れ テストクラス モックの作成 アノテーションによるモックの作成 モックの種類を指定する モックをS2コンテナに登録する 明示的にモックを作成する モックの振る舞いを記録する モックとのインタラクションを再現する モックとのインタラクションを検証する ## 概要 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を使ったテストの流れ 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モードのモックは指定されていないメソッド呼び出しが行われても例外をスローしません． #### モックをS2コンテナに登録する `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));
        }
## モックとのインタラクションを検証する テストメソッドの実行が正常に終了すると自動的にモックとのインタラクションが検証されます． |
| Copyright© 2004-2005, The Seasar Foundation and the others. All rights reserved.