読者です 読者をやめる 読者になる 読者になる

この日記は私的なものであり、所属会社の見解ではありません。 GitHub: takahashikzn

EasyMockを使う

Java


僕はモックオブジェクトの作成にEasyMockを使ってます。


このEasyMock、例えばHttpServletRequestのように、用意するのが大変なオブジェクトをサクっと作成するのに重宝します。

例えば、

こんなメソッドの単体テストを書くとします。

public final class HttpRequestUtil {

    /**
     * リクエストパメータを、扱い易いGenerics型のMapに変換する。
     * 
     * @param req リクエスト
     */
    public static Map<String, List<String>> getRequestParameterGenericsMap(final HttpServletRequest req) {
        
        final Map<String, List<String>> genericsMap = new HashMap<String, List<String>>();
    
        @SuppressWarnings("unchecked")
        final Enumeration<String> parameterNames = (Enumeration<String>) req.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            final String paramName = parameterNames.nextElement();
            final String[] paramValues = req.getParameterValues(parameterName);
            
            genericsMap.put(parameterName, Arrays.asList(paramValues));
        }

        return genericsMap;
    }

}


このメソッドの単体テストを、モックを使わずに書くとこうなるでしょう。

    @Test
    public void testGetRequestParameterGenericsMap() {

        final Vector<String> expectedParameterNames = new Vector<String>();
        expectedParameterNames.add("param1");
        expectedParameterNames.add("param2");

        final Map<String, String[]> expectedParameterValues = new HashMap<String, String[]>();
        expectedParameterValues.put("param1", new String[] { "1" });
        expectedParameterValues.put("param1", new String[] { "2" });

        final HttpServletRequest mockReq = new HttpServletRequest() {
            @Override
            public Enumeration getParameterNames() {
                return expectedParameterNames.elements();
            }

            @Override
            public String[] getParameterValues(final String paramName) {
                return expectedParameterValues.get(paramName);
            }

            // 以下、HttpServletRequestの実装に必要なメソッドの空実装が山ほど続く…

        };
        
        // メソッドの実行
        final Map<String, List<String>> actual = HttpRequestUtil.getRequestParameterGenericsMap(mockReq);

        // 以下、assertが続く        
        assertEquals(...);
    }


HttpServletRequestを使ったことがある方ならご存知だと思いますが、
HttpServletRequestの実装クラスを書くには数百行のコーディングが必要です。
これがまた、超ウザったい。

EasyMockを使うと、

このようにすることができます。

    @Test
    public void testGetRequestParameterGenericsMap() {

        final Vector<String> expectedParameterNames = new Vector<String>();
        expectedParameterNames.add("param1");
        expectedParameterNames.add("param2");
    
        final HttpServletRequest mockReq = EasyMock.createMock(HttpServletRequest.class);
        
        // モックの振る舞いを記述する
        EasyMock.expect(mockReq.getParameterNames()).andReturn(expectedParameterNames.elements()).once();
        EasyMock.expect(mockReq.getParameterValues("param1")).andReturn(new String[] { "1" }).once();
        EasyMock.expect(mockReq.getParameterValues("param2")).andReturn(new String[] { "2" }).once();
        
        // モックの振る舞いを記述完了
        EasyMock.replay(mockReq);
        
        // メソッドの実行
        final Map<String, List<String>> actual = HttpRequestUtil.getRequestParameterGenericsMap(mockReq);

        // 以下、assertが続く        
        assertEquals(...);

        // モックが指定した振る舞いを行ったかどうかを検証
        EasyMock.verify(mockReq);
    }


ウザったいところが、綺麗さっぱりバッサリなくなってます。


もちろん、HttpServletRequestのテスト用モッククラスなんてそこら辺に転がってるわけですが、
一度EasyMockの使い方を覚えてしまうと、今後はこれだけ使ってれば、ほとんどのシチュエーションに対応出来るようになります。
いちいちMockHttpServletRequestなんて(探さなくて/作らなくて)も良い。

要するに

EasyMock使っとけ。ということです…
あ、jMockでも可。僕は使った事ないけど。まあ同じようなものらしいです。はい。