#spring-boot #java-8 #mockito
#весенняя загрузка #java-8 #mockito
Вопрос:
Я написал код в нашем приложении Spring Boot 2 для выполнения вызова стороннего API с помощью HttpURLConnection.
public String loginApi(LoginDTO loginDto)
{
String responseData = null;
HttpURLConnection conn = null;
try {
link = authBaseUrl loginUrl;
url = new URL(link);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty(CONTENT_TYPE, MEDIA_TYPE);
String body = getAuth0LoginDto(loginDto);
// =====================
// For POST only - START
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
os.write(body.getBytes(StandardCharsets.UTF_8));
os.flush();
os.close();
// For POST only - END
// ====================
try (BufferedReader br = (conn.getResponseCode() >= 400
? new BufferedReader(new InputStreamReader(conn.getErrorStream()))
: new BufferedReader(new InputStreamReader(conn.getInputStream())))) {
StringBuilder everything = new StringBuilder();
String output = null;
while ((output = br.readLine()) != null) {
everything.append(output);
}
responseData = everything.toString();
}
} catch (JsonProcessingException e) {
throw new Auth0Exception("Could not create Auth0 Login Body", e);
} catch (IOException e) {
throw new Auth0Exception("Error with Login API", e);
} finally {
if (conn != null) {
conn.disconnect();
}
}
return responseData;
}
Теперь я очень привык проводить реальное интеграционное тестирование, где я делаю реальный вызов веб-службы и проверяю результаты.
Теперь меня просят использовать строго Mockito, а не PowerMockito, а не EasyMock, для создания имитационных тестов, и я никогда раньше этого не делал. Мои знания о Mockito также слабы, поскольку я не использовал его очень долгое время.
Итак, я знаю, что об этом спрашивали раньше, и я действительно искал в Интернете, и я действительно не нашел полный фрагмент кода в качестве примера. Я вижу фрагменты кода, в которых отсутствуют фрагменты, и я недостаточно осведомлен, чтобы добавить эти части самостоятельно.
Я знаю, что фактическая реализация этого кода работает нормально, и интеграционный тест также работает нормально. Но, что я видел раньше, так это то, что некоторым пользователям говорят, что им нужно изменить свой клиентский код, чтобы заставить тесты mockito работать.
Если я не получу макетные тесты, работающие для HttpURLConnection, тогда я буду вынужден переключиться на RestTemplate и Mocking, поскольку мой коллега настаивает, что мы все равно используем RestTemplate.
Спасибо!
Комментарии:
1. Почему бы вам просто не извлечь
HTTPUrlConnection
создание новым методом. Тогда это легко подделать.2. Я бы не стал разбираться в том, что вы имеете в виду… Мне нужен пример для копирования. Спасибо!
Ответ №1:
Поскольку вы попросили небольшой пример, который не имеет смысла, но должен показать идею:
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.HttpURLConnection;
import java.net.URL;
public class App {
public int status(URL url) {
HttpURLConnection urlConnection = null;
try {
urlConnection = create(url);
return urlConnection.getResponseCode();
} catch (IOException e) {
throw new UncheckedIOException(e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
HttpURLConnection create(URL url) throws IOException {
return (HttpURLConnection) url.openConnection();
}
}
Я бы реализовал это с помощью spy и, как я рекомендовал, mocked HttpURLConnection
:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
@ExtendWith(MockitoExtension.class)
class AppTest {
@Spy
App app;
@Mock
HttpURLConnection connection;
@Test
void status() throws IOException {
int expected = 200;
doReturn(connection).when(app).create(any());
doReturn(expected).when(connection).getResponseCode();
URL url = new URL("http://www.google.ats");
int status = app.status(url);
Assertions.assertEquals(expected, status);
}
}