EasyMock引数マッチャー

EasyMock引数マッチャー

1. 概要

このチュートリアルでは、EasyMock引数マッチャーについて説明します。 We’ll discuss different types of predefined matchers and how to create a custom matcherも同様です。

EasyMockの基本については、introduction to EasyMockの記事ですでに説明しているため、EasyMockに慣れるために、最初に読む必要がある場合があります。

2. 簡単なモックの例

さまざまなマッチャーの調査を開始する前に、コンテキストを見てみましょう。 このチュートリアル全体を通して、例ではかなり基本的なユーザーサービスを使用します。

単純なIUserServiceインターフェースは次のとおりです。

public interface IUserService {
    public boolean addUser(User user);
    public List findByEmail(String email);
    public List findByAge(double age);
}

そして、関連するUserモデル:

public class User {
    private long id;
    private String firstName;
    private String lastName;
    private double age;
    private String email;

    // standard constructor, getters, setters
}

したがって、例で使用するために、IUserServiceをモックすることから始めます。

private IUserService userService = mock(IUserService.class);

それでは、EasyMock引数マッチャーについて見ていきましょう。

3. 平等マッチャー

まず、eq()マッチャーを使用して、新しく追加されたUserを照合します。

@Test
public void givenUserService_whenAddNewUser_thenOK() {
    expect(userService.addUser(eq(new User()))).andReturn(true);
    replay(userService);

    boolean result = userService.addUser(new User());
    verify(userService);
    assertTrue(result);
}

このマッチャーは、プリミティブとオブジェクトの両方、およびuses the equals() method for objectsで使用できます。

同様に、same()マッチャーを使用して、特定のUserを照合できます。

@Test
public void givenUserService_whenAddSpecificUser_thenOK() {
    User user = new User();

    expect(userService.addUser(same(user))).andReturn(true);
    replay(userService);

    boolean result = userService.addUser(user);
    verify(userService);
    assertTrue(result);
}

The same() matcher compares arguments using “==”は、この場合はUserインスタンスを比較することを意味します。

マッチャーを使用しない場合、引数はデフォルトでequals().を使用して比較されます

配列の場合、Arrays.equals()メソッドに基づくaryEq()マッチャーもあります。

4. Anyマッチャー

anyInt()anyBoolean()anyDouble()などのような複数のマッチャーがあります。 These specify that the argument should have the given type.

anyString()を使用して、予想されるemailを任意のString値に一致させる例を見てみましょう。

@Test
public void givenUserService_whenSearchForUserByEmail_thenFound() {
    expect(userService.findByEmail(anyString()))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByEmail("[email protected]");
    verify(userService);
    assertEquals(0,result.size());
}

isA()を使用して、引数を特定のクラスのインスタンスに一致させることもできます。

@Test
public void givenUserService_whenAddUser_thenOK() {
    expect(userService.addUser(isA(User.class))).andReturn(true);
    replay(userService);

    boolean result = userService.addUser(new User());
    verify(userService);
    assertTrue(result);
}

ここでは、addUser()メソッドパラメータがUser.型であると想定していると主張しています。

5. ヌルマッチャー

次に、we can use the isNull() and notNull() matchers to match null values.

次の例では、追加されたUser値がnullの場合に、isNull()マッチャーを使用して照合します。

@Test
public void givenUserService_whenAddNull_thenFail() {
    expect(userService.addUser(isNull())).andReturn(false);
    replay(userService);

    boolean result = userService.addUser(null);
    verify(userService);
    assertFalse(result);
}

同様の方法で、追加されたユーザー値がnullでない場合は、notNull()を照合することもできます。

@Test
public void givenUserService_whenAddNotNull_thenOK() {
    expect(userService.addUser(notNull())).andReturn(true);
    replay(userService);

    boolean result = userService.addUser(new User());
    verify(userService);
    assertTrue(result);
}

6. Stringマッチャー

String引数で使用できる便利なマッチャーが複数あります。

まず、startsWith()マッチャーを使用して、ユーザーのメールプレフィックスを照合します。

@Test
public void whenSearchForUserByEmailStartsWith_thenFound() {
    expect(userService.findByEmail(startsWith("test")))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByEmail("[email protected]");
    verify(userService);
    assertEquals(0,result.size());
}

同様に、メールのサフィックスにはendsWith()マッチャーを使用します。

@Test
public void givenUserService_whenSearchForUserByEmailEndsWith_thenFound() {
    expect(userService.findByEmail(endsWith(".com")))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByEmail("[email protected]");
    verify(userService);
    assertEquals(0,result.size());
}

より一般的には、contains()を使用して、メールを特定の部分文字列と照合できます。

@Test
public void givenUserService_whenSearchForUserByEmailContains_thenFound() {
    expect(userService.findByEmail(contains("@")))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByEmail("[email protected]");
    verify(userService);
    assertEquals(0,result.size());
}

または、matches()を使用して、メールを特定の正規表現に一致させることもできます。

@Test
public void givenUserService_whenSearchForUserByEmailMatches_thenFound() {
    expect(userService.findByEmail(matches(".+\\@.+\\..+")))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByEmail("[email protected]");
    verify(userService);
    assertEquals(0,result.size());
}

7. ナンバーマッチャー

また、使用できる数値用のいくつかのマッチャーがあります。

lt()マッチャーを使用してage引数を100未満に一致させる例を見てみましょう。

@Test
public void givenUserService_whenSearchForUserByAgeLessThan_thenFound() {
    expect(userService.findByAge(lt(100.0)))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByAge(20);
    verify(userService);
    assertEquals(0,result.size());
}

同様に、geq()を使用して、age引数を10以上に一致させます。

@Test
public void givenUserService_whenSearchForUserByAgeGreaterThan_thenFound() {
    expect(userService.findByAge(geq(10.0)))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByAge(20);
    verify(userService);
    assertEquals(0,result.size());
}

利用可能な番号マッチャーは次のとおりです。

  • lt() –指定された値未満

  • leq() –以下

  • gt() –より大きい

  • geq() –以上

8. マッチャーを組み合わせる

and()or()、およびnot()マッチャーを使用して複数のマッチャーを組み合わせることもできます。

2つのマッチャーを組み合わせて、年齢の値が10より大きく100より小さいことを確認する方法を見てみましょう。

@Test
public void givenUserService_whenSearchForUserByAgeRange_thenFound() {
    expect(userService.findByAge(and(gt(10.0),lt(100.0))))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByAge(20);
    verify(userService);
    assertEquals(0,result.size());
}

確認できるもう1つの例は、not()endsWith()を組み合わせて、「。com」で終わらないメールを照合することです。

@Test
public void givenUserService_whenSearchForUserByEmailNotEndsWith_thenFound() {
    expect(userService.findByEmail(not(endsWith(".com"))))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByEmail("[email protected]");
    verify(userService);
    assertEquals(0,result.size());
}

9. カスタムマッチャー

最後に、カスタムEasyMockマッチャーを作成する方法について説明します。

目標は、指定された値以上の長さの文字列に一致する単純なminCharCount()マッチャーを作成することです。

@Test
public void givenUserService_whenSearchForUserByEmailCharCount_thenFound() {
    expect(userService.findByEmail(minCharCount(5)))
      .andReturn(Collections.emptyList());
    replay(userService);

    List result = userService.findByEmail("[email protected]");
    verify(userService);
    assertEquals(0,result.size());
}

カスタム引数マッチャーを作成するには、次のことが必要です。

  • IArgumentMatcherインターフェースを実装する新しいクラスを作成します

  • 新しいマッチャー名で静的メソッドを作成し、reportMatcher()を使用して上記のクラスのインスタンスを登録します

minCharCount()メソッド内で匿名クラスを宣言する両方のステップを見てみましょう。

public static String minCharCount(int value){
    EasyMock.reportMatcher(new IArgumentMatcher() {
        @Override
        public boolean matches(Object argument) {
            return argument instanceof String
              && ((String) argument).length() >= value;
        }

        @Override
        public void appendTo(StringBuffer buffer) {
            buffer.append("charCount(\"" + value + "\")");
        }
    });
    return null;
}

また、IArgumentMatcherインターフェースにはmatches()appendTo(). の2つのメソッドがあることに注意してください

最初のメソッドには、マッチャーの引数の検証とロジックが含まれ、2番目のメソッドは、失敗した場合に出力されるマッチャーのString表現を追加するために使用されます。

10. 結論

さまざまなデータ型のEasyMock事前定義引数マッチャーと、カスタムマッチャーの作成方法について説明しました。

例の完全なソースコードは、over on GitHubで入手できます。