JMockitを使用した単体テスト2
引数にモックを渡す
テスト対象
public final class RequestUtils { public static String getUserAgent(final HttpServletRequest request) { if (request == null) { throw new IllegalArgumentException("request : null"); } return request.getHeader("user-agent"); } }
一番簡単なパターンですが、上記のように、テスト対象のメソッドの引数としてモックを渡す場合には、次のようにテストを記述します。
テストクラス
@Test public void testGetUserAgent() { final String userAgent = "USER-AGENT"; new Expectations() { // (1) モックフィールド ここにモックを宣言する HttpServletRequest mockRequest; { // (2) モックの振る舞いを記述する // getHeaderが呼ばれたときの戻り値をreturnsで指定する mockRequest.getHeader("user-agent"); returns(userAgent); } }; // テスト対象のメソッドを実行 final String result = RequestUtils.getUserAgent(mockRequest); // 結果をチェック assertEquals(userAgent, result); }
Expectationsを使用して、テスト対象メソッドで使用されているモックの振る舞い等を記述します。
(1) 無名クラスのフィールドにモックにしたいクラスを記述します(インタフェースでも抽象クラスでもかまいません)。上記ではHttpServletRequestをモックとしています。
(2) getHeader("user-agent")の戻り値として、userAgentを返すようにreturns(userAgnet)としています。ExceptionやErrorをスローしたいときには、throwException(new Exception())やthrowError(new Error())と記述します。
テスト対象のメソッドを実行すると、Expectationsで記録(record)した振る舞いが再現(replay)されます。また、デフォルトで、HttpServletRequest#getHeader("user-agent")が実行されたこともチェック(verify)します。もし、呼ばれなければテストは失敗します。
モックは、Expectations内で宣言することもできますが、テストクラスのフィールドに宣言する場合は@Mockedを付与します。
public class RequestUtilsTest { @Mocked private HttpServletRequest mockRequest;
ここで使用しているExpectationsは呼ばれたメソッドの順番に厳格ですので、呼ばれる順番を正確に記述する必要があります。厳格にチェックしないのであれば、NonStrictExpectationsを使用します。