Как подсказал @deterb, это возможно с Mockito, но вы должны знать имя метода или устанавливать ожидания для каждого метода. Вот пример:
Перемешиваемый интерфейс:
public interface MyInterface {
void allowedMethod();
void disallowedMethod();
}
Пользовательский класс, который ловит AssertionError
:
public class UserClass {
public UserClass() {
}
public static void throwableCatcher(final MyInterface myInterface) {
try {
myInterface.allowedMethod();
myInterface.disallowedMethod();
} catch (final Throwable t) {
System.out.println("Catched throwable: " + t.getMessage());
}
}
}
И тест Мокито:
@Test
public void testMockito() throws Exception {
final MyInterface myInterface = mock(MyInterface.class);
UserClass.throwableCatcher(myInterface);
verify(myInterface, never()).disallowedMethod(); // fails here
}
То же самое возможно с EasyMock, но требуется некоторая работа:
@Test
public void testEasyMock() throws Exception {
final AtomicBoolean called = new AtomicBoolean();
final MyInterface myInterface = createMock(MyInterface.class);
myInterface.allowedMethod();
myInterface.disallowedMethod();
final IAnswer<? extends Object> answer = new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
System.out.println("answer");
called.set(true);
throw new AssertionError("should not call");
}
};
expectLastCall().andAnswer(answer).anyTimes();
replay(myInterface);
UserClass.throwableCatcher(myInterface);
verify(myInterface);
assertFalse("called", called.get()); // fails here
}
К сожалению, вы также должны знать имена методов здесь, и вы должны определить ожидания как myInterface.disallowedMethod()
и expectLastCall().andAnswer(answer).anyTimes()
.
Другая возможность - создать прокси с классом Proxy
(с пользовательским InvocationHandler
) и использовать его в качестве фиктивного объекта. Это определенно требует больше работы, но это может быть самое настраиваемое решение.
Наконец, не забывайте, что также возможно создать пользовательскую реализацию с делегированием или без делегирования объекту-модели EasyMock. Вот один с делегацией:
public class MockedMyInterface implements MyInterface {
private final MyInterface delegate;
private final AtomicBoolean called = new AtomicBoolean();
public MockedMyInterface(final MyInterface delegate) {
this.delegate = delegate;
}
@Override
public void allowedMethod() {
delegate.allowedMethod();
}
@Override
public void disallowedMethod() {
called.set(true);
throw new AssertionError("should not call");
}
public boolean isCalled() {
return called.get();
}
}
И тест для него:
@Test
public void testEasyMockWithCustomClass() throws Exception {
final MyInterface myInterface = createMock(MyInterface.class);
myInterface.allowedMethod();
final MockedMyInterface mockedMyInterface =
new MockedMyInterface(myInterface);
replay(myInterface);
UserClass.throwableCatcher(mockedMyInterface);
verify(myInterface);
assertFalse("called", mockedMyInterface.isCalled()); // fails here
}