1. 概要

このチュートリアルでは、EasyMock引数マッチャーについて説明します。 さまざまなタイプの事前定義されたマッチャーと、カスタムマッチャーの作成方法についても説明します。

EasyMockの基本についてはEasyMockの概要の記事ですでに説明しているので、EasyMockに慣れるために最初に読む必要があるかもしれません。

2. 簡単なモッキングの例

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

シンプルなIUserServiceインターフェイスは次のとおりです。

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

および関連するユーザーモデル:

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);
}

このマッチャーはプリミティブとオブジェクトの両方で使用でき、はオブジェクトにequals()メソッドを使用します。

同様に、 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);
}

same()マッチャーは、「==」を使用して引数を比較します。つまり、この場合はUserインスタンスを比較します。

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

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

4.4。 どれでもマッチャー

anyInt() anyBoolean() anyDouble()などのような複数のマッチャーがあります。 これらは、引数が指定されたタイプである必要があることを指定します。

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

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

    List<User> 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. ヌルマッチャー

次に、 isNull()およびnotNull()マッチャーを使用してnull値を照合できます。

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

@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.6。 弦マッチャー

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

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

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

    List<User> 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<User> 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<User> 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<User> 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<User> 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<User> 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<User> 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<User> 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<User> 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 インターフェイスには2つの方法があります。 matches() appendTo()。 

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

10. 結論

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

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