Использование 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.