Если вы используете PowerMock + Mockito, вы можете написать тест, подобный этому:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Tests.class)
public class Tests {
@Test
public void testHandledByFirst() throws Exception {
Request req = ...;
Handler h1 = mock(Handler.class);
Handler h2 = mock(Handler.class);
when(h1, "setSuccessor", h2).thenCallRealMethod();
when(h1, "handleRequestImpl", req).thenReturn(true);
h1.setSuccessor(h2);
h1.handleRequest(req);
verify(h2, times(0)).handleRequest(req);
}
@Test
public void testHandledBySecond() throws Exception {
Request req = ...;
Handler h1 = mock(Handler.class);
Handler h2 = mock(Handler.class);
when(h1, "setSuccessor", h2).thenCallRealMethod();
when(h1, "handleRequestImpl", req).thenReturn(false);
h1.setSuccessor(h2);
h1.handleRequest(req);
verify(h2, times(1)).handleRequest(req);
}
}
Который проверит, что метод вашего второго обработчика вызывается, когда первый возвращает false, и что он не вызывается, когда возвращает true.
Другой вариант - следовать общеизвестному правилу «отдавать предпочтение композиции по наследованию» и менять свой класс на что-то вроде этого:
public interface Callable {
public boolean call(Request request);
}
public class Handler {
private Callable thisCallable;
private Callable nextCallable;
public Handler(Callable thisCallable, Callable nextCallable) {
this.thisCallable = thisCallable;
this.nextCallable = nextCallable;
}
public boolean handle(Request request) {
return thisCallable.call(request)
|| (nextCallable != null && nextCallable.call(request));
}
}
Затем вы можете смоделировать его таким образом (или использовать почти любую поддельную среду, поскольку у вас нет защищенных методов):
* * 1010
В этом решении вы также можете настроить наследование Handler после Callable, а затем обернуть его поверх любого другого вызываемого объекта, который может иметь преемника, и использовать обработчик вместо исходного вызываемого объекта; это гораздо более гибко.