Я сталкивался с подобной проблемой, когда насмешливый строителей, так что я бы экспериментировать, чтобы увидеть, если есть способ лучше.
Как сказал г-н Лоун, возможно, лучше, если вы можете избежать этого, в первую очередь, поскольку это не ваш код, и его можно считать «просто работающим», но я думал, что дам ему пойти в любом случае ,
Я придумал (возможно, грубый) способ сделать это, используя «ответы по умолчанию» в Mockito. Я все еще решаю, нравится мне это или нет.
Вот мой строитель ...
public class MyBuilder {
private StringBuilder my;
public MyBuilder() {
my = new StringBuilder();
}
public MyBuilder name(String name) {
my.append("[name=").append(name).append("]");
return this;
}
public MyBuilder age(String age) {
my.append("[age=").append(age).append("]");
return this;
}
public String create() {
return my.toString();
}
}
(Довольно основных прав?)
Я получил мой тест, чтобы посмотреть что-то вроде этого ...
// Create a "BuilderMocker" (any better name suggestions welcome!)
BuilderMocker<MyBuilder> mocker = BuilderMocker.forClass(MyBuilder.class);
// Get the actual mock builder
MyBuilder builder = mocker.build();
// expect this chain of method calls...
mocker.expect().name("[NAME]").age("[AGE]");
// expect this end-of-chain method call...
Mockito.when(builder.create()).thenReturn("[ARGH!]");
Теперь, если я следующие ...
System.out.println(builder.name("[NAME]").age("[AGE]").create());
... Я ожидаю, что «[ARGH!]» Будет выводиться.
Если я изменил последнюю строку ...
System.out.println(builder.name("[NOT THIS NAME]").age("[AGE]").create());
... тогда я ожидаю, что он сломается с помощью NullPointerException.
Вот собственно «BuilderMocker» ...
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
public class BuilderMocker<T> {
private Class<T> clazz;
private T recorder;
private T mock;
// Create a BuilderMocker for the class
public static <T> BuilderMocker<T> forClass(Class<T> clazz) {
return new BuilderMocker<T>(clazz);
}
private BuilderMocker(Class<T> clazz) {
this.clazz = clazz;
this.mock = mock(clazz);
createRecorder();
}
// Sets up the "recorder"
private void createRecorder() {
recorder = mock(clazz, withSettings().defaultAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
// If it is a chained method...
if (invocation.getMethod().getReturnType().equals(clazz)) {
// Set expectation on the "real" mock...
when(invocation.getMethod().invoke(mock, invocation.getArguments())).thenReturn(mock);
return recorder;
}
return null;
}
}));
}
// Use this to "record" the expected method chain
public T expect() {
return recorder;
}
// Use this to get the "real" mock...
public T build() {
return mock;
}
}
Не уверен, что если есть «встроенный» способ сделать это в Mockito, но это, кажется, работает.
Для чего это стоит, я думаю, что вы собираетесь слишком низкоуровневым. Вы должны только тестировать ** свой ** код, а не проверять, работает ли Elasticsearch: предположите, что это так. Поэтому я предполагаю, что у вас есть метод, который обертывает весь этот код: например. 'public String [] search (searchParams ..) {SearchResponse response = client.prepareSearch (index) .. и т. д .; SearchHit [] hits = response.getHits(). GetHits(); обратные хиты; } '. Ваш тест должен высмеять ваш метод 'search' и вернуть mock' String [] 'результаты для разных входов. –