EasyMock引数マッチャー
1概要
このチュートリアルでは、EasyMock引数マッチャーを探ります。
さまざまな種類の定義済みマッチャーとカスタムマッチャーの作成方法についても説明します
。
EasyMockの基本についてはリンクですでに説明しています。
2単純なモッキングの例
さまざまなMatcherの探索を始める前に、コンテキストを見てみましょう。このチュートリアルでは、この例ではかなり基本的なユーザーサービスを使用します。
これが私たちのシンプルな
IUserService
インターフェースです。
public interface IUserService {
public boolean addUser(User user);
public List<User> findByEmail(String email);
public List<User> 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平等マッチャー
まず、新しく追加された
User
と一致させるために
eq()
matcherを使用します。
@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()
メソッドを使います
。
同様に、特定の
User
と一致させるために
same()
matcherを使用できます。
@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()
matcherは、 ”
==”
** を使用して引数を比較します。つまり、ここでは
User
インスタンスを比較します。
マッチャーを使用しない場合、引数はデフォルトで__equals()を使用して比較されます。
配列の場合は、
Arrays.equals()
メソッドに基づく
aryEq()
matcherもあります。
4任意の
Matcher
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
値を一致させることができます。
次の例では、追加された
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
引数と共に使用できる便利なマッチャーは複数あります。
まず、
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());
}
同様に、Eメールサフィックスに
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. ナンバーマッチャー
私達はまた私達が使用できる数値のための少数のmatcherを持っています。
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());
}
同様に、age引数が10以上になるように
geq()
を使用します。
@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 Matcherを組み合わせる
と()
、
or()
と
not()
のマッチャーを使って複数のマッチャーを組み合わせることもできます。
年齢値が10を超え100未満であることを確認するために2つのマッチャーを組み合わせる方法を見てみましょう。
@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());
}
私たちが見ることができるもう一つの例は、“。com”で終わらない電子メールにマッチさせるために
not()
と
endsWith()
を組み合わせることです:
@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で定義されているさまざまなデータ型の引数マッチャーとカスタムマッチャーの作成方法について説明しました。
例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/testing-modules/mocks/mock-comparisons[GitHubで利用可能]です。