Как захватить HTTP-запрос и имитировать его ответ на Java?
Скажем, приложение Java запрашивает http://www.google.com/...
и нет способа настроить унаследованную библиотеку (делая такие запросы внутри), поэтому я не могу заглушить или заменить этот URL.
Пожалуйста, поделитесь некоторыми лучшими практиками по созданию макета типа
whenCalling("http://www.google.com/some/path").withMethod("GET").thenExpectResponse("HELLO")
поэтому запрос любого HTTP-клиента на этот URL-адрес будет перенаправлен на макет и заменен этим ответом "HELLO"
в контексте текущего процесса JVM.
Я пытался найти решение с помощью WireMock, Mockito или Hoverfly, но похоже, что они делают что-то другое. Наверное, я просто неправильно их использовал.
Не могли бы вы показать простую настройку из main
метод вроде:
- создать макет
- начать имитацию симуляции
- сделать запрос к URL-адресу произвольным HTTP-клиентом (не связанным с имитационной библиотекой)
- получить поддельный ответ
- остановить имитацию симуляции
- сделайте тот же запрос, что и на шаге 3
- получить реальный ответ от URL
1 ответ
Вот как добиться желаемого с помощью симулятора API.
В этом примере демонстрируются два разных способа настройки Embedded API Simulator в качестве HTTP-прокси для клиента Spring RestTemplate. Ознакомьтесь с документацией (цитата из вопроса) "унаследованной библиотеки" - часто клиенты на основе Java полагаются на системные свойства, описанные здесь, или могут предложить какой-либо способ настройки HTTP-прокси с помощью кода.
package others;
import static com.apisimulator.embedded.SuchThat.*;
import static com.apisimulator.embedded.http.HttpApiSimulation.*;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.URI;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import com.apisimulator.embedded.http.JUnitHttpApiSimulation;
public class EmbeddedSimulatorAsProxyTest
{
// Configure an API simulation. This starts an instance of
// Embedded API Simulator on localhost, default port 6090.
// The instance is automatically stopped when the test ends.
@ClassRule
public static final JUnitHttpApiSimulation apiSimulation = JUnitHttpApiSimulation
.as(httpApiSimulation("my-sim"));
@BeforeClass
public static void beforeClass()
{
// Configure simlets for the API simulation
// @formatter:off
apiSimulation.add(simlet("http-proxy")
.when(httpRequest("CONNECT"))
.then(httpResponse(200))
);
apiSimulation.add(simlet("test-google")
.when(httpRequest()
.whereMethod("GET")
.whereUriPath(isEqualTo("/some/path"))
.whereHeader("Host", contains("google.com"))
)
.then(httpResponse()
.withStatus(200)
.withHeader("Content-Type", "application/text")
.withBody("HELLO")
)
);
// @formatter:on
}
@Test
public void test_using_system_properties() throws Exception
{
try
{
// Set these system properties just for this test
System.setProperty("http.proxyHost", "localhost");
System.setProperty("http.proxyPort", "6090");
RestTemplate restTemplate = new RestTemplate();
URI uri = new URI("http://www.google.com/some/path");
ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);
Assert.assertEquals(200, response.getStatusCode().value());
Assert.assertEquals("HELLO", response.getBody());
}
finally
{
System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
}
}
@Test
public void test_using_java_net_proxy() throws Exception
{
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
// A way to configure API Simulator as HTTP proxy if the HTTP client supports it
Proxy proxy = new Proxy(Type.HTTP, new InetSocketAddress("localhost", 6090));
requestFactory.setProxy(proxy);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(requestFactory);
URI uri = new URI("http://www.google.com/some/path");
ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);
Assert.assertEquals(200, response.getStatusCode().value());
Assert.assertEquals("HELLO", response.getBody());
}
@Test
public void test_direct_call() throws Exception
{
RestTemplate restTemplate = new RestTemplate();
URI uri = new URI("http://www.google.com");
ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);
Assert.assertEquals(200, response.getStatusCode().value());
Assert.assertTrue(response.getBody().startsWith("<!doctype html>"));
}
}
При использовании maven добавьте в проект: pom.xml
чтобы включить Embedded API Simulator в качестве зависимости:
<dependency>
<groupId>com.apisimulator</groupId>
<artifactId>apisimulator-http-embedded</artifactId>
<version>1.6</version>
</dependency>
... и это указывает на репозиторий:
<repositories>
<repository>
<id>apisimulator-github-repo</id>
<url>https://github.com/apimastery/APISimulator/raw/maven-repository</url>
</repository>
</repositories>