Powermock содержит () не работает
Я пытаюсь смоделировать HTTP-вызов с помощью PowerMockito, но у меня возникли некоторые проблемы с contains()
функция. Мой план состоит в том, чтобы проверить, содержит ли путь определенную строку, а затем я возвращаю фиктивный объект. Итак, у меня есть следующая функция:
import static com.mscharhag.oleaster.runner.StaticRunnerSupport.*;
import static org.mockito.Matchers.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static org.powermock.api.mockito.PowerMockito.*;
private static <T> void mockResponse(Class<T> type, T response, String pathContains) throws Exception
{
mockStatic(ClientBuilder.class);
Client client = mock(Client.class);
when(ClientBuilder.class, "newClient").thenReturn(client);
WebTarget webTarget = mock(WebTarget.class);
when(client.target(anyString())).thenReturn(webTarget);
//This is what doesn't work
when(webTarget.path(contains(pathContains))).thenReturn(webTarget);
when(webTarget.queryParam(any(), any())).thenReturn(webTarget);
Invocation.Builder invocationBuilder = mock(Invocation.Builder.class);
when(webTarget.request()).thenReturn(invocationBuilder);
Invocation invocation = mock(Invocation.class);
when(invocationBuilder.buildGet()).thenReturn(invocation);
Response res = mock(Response.class);
when(invocation.invoke()).thenReturn(res);
when(res.readEntity(type)).thenReturn(response);
}
mockResponse(GenreList.class, new GenreList(new Genre(0, "g")), "genre");
Проблема в том, что я получаю нулевой указатель при попытке сделать HTTP-вызов:
Response res = client.target(theMovieDbURL)
.path("/3/genre/movie/list")
.queryParam("api_key", apiKey)
.request()
.buildGet()
.invoke();
Если я, где изменить макет из contains()
в anyString()
это работает как шарм, но мне нужно иметь разные ответы для разных путей, поэтому я не могу оставить это как anyString()
, Я пытался изменить его на eq()
также, но это тоже не работает.
Что мне здесь не хватает?
из моего gradle:
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.6.6'
testCompile group: 'org.powermock', name: 'powermock-api-mockito', version: '1.6.6'
testCompile group: 'org.powermock', name: 'powermock-module-junit4-rule', version: '1.6.6'
1 ответ
Больше без ответа: вы идете по неправильной кроличьей норе здесь.
Дело в том, что цель теста - убедиться, что конкретный производственный код реализует то требование, которое должен охватывать тест. Ничего больше.
Приводит к тому, что вы предпочитаете несколько простых, простых тестов, а не один кусок кода, способный обрабатывать множество различных аспектов.
Значение: вы не идете и не начинаете использовать
when(webTarget.path(contains(pathContains))).thenReturn(webTarget);
где у вас есть различные возможности, которые может содержать содержащаяся (). Вместо этого у вас есть n тестов, которые явно говорят
when(webTarget.path(contains(A))).thenReturn(webTargetA);
...
when(webTarget.path(contains(B))).thenReturn(webTargetB);
Другими словами: вы намереваетесь как-то выразить умную "бизнес-логику" в своем тестовом коде. Вы хотите сделать это "умным". Не делай этого. Вместо этого сосредоточьтесь на написании тестового кода, который, как уже говорилось, прямо создает конкретную настройку, а затем тестирует одну вещь.
Другими словами: в вашем тестовом коде не должно быть необходимости указывать конкретные возвращаемые значения. Потому что вы определяете настройки (и, следовательно, пути), которые увидит ваш производственный код. Вы говорите, что выбираете путь A для одного теста, а путь B в другом тесте. И тогда ваше желание разработать, если / то логика исчезает в воздухе.