Использование EasyMock подразумевает статическую генерацию ответов из expect(), когда уже на стадии написания теста известно, что вернёт метод и какие будут его значения. На случай, если этого недостаточно, в EasyMock предусмотрено два вызова, позволяющих создавать возвращаемый из mock-объекта результат во время исполнения.
IAnswer
Первый вариант — использование функционального интерфейса IAnswer.
1
2
3
4
5
6
7
8
9
10
11
12
|
@Test
public void testMutatedUser() {
expect(testedObject.findOne("TEST")).andStubAnswer(() -> {
User mutatedUser = new User();
mutatedUser.setUsername((String)getCurrentArguments()[0]);
return mutatedUser;
});
replay(testedObject);
assertThat(testedObject.findOne("TEST").getUsername(), is("TEST"));
}
|
Вызовы andStubAnswer() и andAnswer() принимают лямбда-выражение (или, если быть точным, реализацию интерфейса IAnswer), которое должно создать возвращаемый объект и вернуть его. При этом лябмда-выражение имеет доступ к параметрам вызываемого метода: getCurrentArguments() возвращает массив Object[], каждый элемент которого — соответствующий по порядку аргумент вызываемого метода.
Delegate
Вызовы andStubDelegateTo() и andDelegateTo() наоборот, принимают объект вызываемого типа и совершают вызов на нём, а не на mock объекте:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Test
public void testMutatedUserConcreate() {
expect(testedObject.findOne("TEST")).andStubDelegateTo(new UserRepository() {
@Override
public User findOne(String login) {
return testUser();
}
@Override
public void save(User u) {
return;
}
});
replay(testedObject);
assertThat(testedObject.findOne("TEST"), is(testUser()));
}
|
Поскольку делегат является непосредственной реализацией mock объекта, то параметры вызываемого метода передаются непосредственно в соответствующией метод делегата, а не массивом, как в случае с getCurrentArguments(). С одной стороны, этот подход более типобезопасен и проверяется во время компиляции. С другой стороны, делегат фактически является ручной реализацией mock-объекта, что несколько неудобно и вызывает вопрос необходимости вообще использовать EasyMock в этом случае.
Код примера доступен на github.