v78*_*v78 8 java proxy webservice-client spring-boot wiremock
我想为以下 e2e 场景添加一个测试:
我的应用程序通过内部代理服务器向外部服务发出 Web 请求,代理服务器操作请求正文,将请求转发到目标主机并返回返回的响应。
举例来说,我对external.service/an/endpoint(通过my-proxy-server)正文做了一个发布请求
{
"card_number": "<proxy server pls fill the cc details>"
}
Run Code Online (Sandbox Code Playgroud)
代理服务器修改请求填写cc详细信息并转发给external.service/an/endpointwith body
{
"card_number": "372735466563005"
}
Run Code Online (Sandbox Code Playgroud)
external.service 返回状态 OK。代理服务器不加修改地返回响应。
如何使用wiremock 测试此工作流程?我可以WireMock.stubFor()为external.service,但我不知道如何使有线模拟代理与我的 Web 客户端的代理设置一起工作。查看测试,实际上,Rest Template 测试restTemplateWithWireMockAsProxyServer按预期工作,通过代理路由我的请求,但webClientWithWireMockAsProxyServer我的 RCA 出现错误:
20:06:59.165 [qtp105751207-24] DEBUG wiremock.org.eclipse.jetty.server.HttpChannel - REQUEST for //localhost:58978localhost:58978 on HttpChannelOverHttp@4a71ab50{r=1,c=false,c=false/false,a=IDLE,uri=//localhost:58978localhost:58978,age=0}
CONNECT //localhost:58978localhost:58978 HTTP/1.1
Host: localhost:58978
Run Code Online (Sandbox Code Playgroud)
正如这里提到的,这些通过 wiremock 代理的调用是不可能的。但是我所有的网址都像http://localhost:<port>,这意味着我没有进行任何 https 调用。
package com.spotnana.obt.supplier.services;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.http.RequestMethod;
import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.nio.charset.StandardCharsets;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHeaders;
import org.apache.http.conn.HttpHostConnectException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.client.reactive.ReactorResourceFactory;
import org.springframework.util.SocketUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.tcp.ProxyProvider;
@Slf4j
public class SimpleWiremockProxyServerTest {
private final String HOST = "localhost";
private final String MOCK_ENDPOINT = "/my/endpoint";
private WireMockServer targetServer;
private WireMockServer proxyServer;
private WireMock targetWireMock;
private WireMock proxyWireMock;
private String targetBaseUrl;
@Before
public void setup() {
final int targetPort = SocketUtils.findAvailableTcpPort();
this.targetServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(targetPort));
this.targetServer.start();
this.targetWireMock = new WireMock(targetPort);
this.targetWireMock.resetMappings();
this.targetBaseUrl = "http://" + HOST + ":" + targetPort;
final int proxyPort = SocketUtils.findAvailableTcpPort();
this.proxyServer =
new WireMockServer(
WireMockConfiguration.wireMockConfig().port(proxyPort).enableBrowserProxying(true));
this.proxyServer.start();
this.proxyWireMock = new WireMock(proxyPort);
this.proxyWireMock.resetMappings();
}
@After
public void tearDown() throws HttpHostConnectException {
this.targetWireMock.shutdown();
this.targetServer.stop();
try {
this.proxyWireMock.shutdown();
this.proxyServer.stop();
} catch (final Exception ex) {
log.warn("Proxy server is shutdown already");
}
}
@Test
public void restTemplateWithWireMockAsProxyServer() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(HOST, this.proxyServer.port()));
requestFactory.setProxy(proxy);
final var reqPatternBuilder =
RequestPatternBuilder.newRequestPattern(
RequestMethod.GET, WireMock.urlEqualTo(MOCK_ENDPOINT));
final var mappingBuilder =
WireMock.get(WireMock.urlEqualTo(reqPatternBuilder.build().getUrl()));
reqPatternBuilder
.withHeader(HttpHeaders.ACCEPT, WireMock.containing(MediaType.APPLICATION_JSON_VALUE))
.withHeader(
HttpHeaders.ACCEPT_CHARSET,
WireMock.containing(StandardCharsets.UTF_8.name().toUpperCase()));
mappingBuilder.willReturn(
WireMock.aResponse()
.withStatus(HttpStatus.OK.value())
.withBody("{ \"success\": true }")
.withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE));
this.targetWireMock.register(mappingBuilder);
ResponseEntity<String> responseEntity =
new RestTemplate(requestFactory)
.getForEntity(this.targetBaseUrl + MOCK_ENDPOINT, String.class);
Assert.assertEquals(responseEntity.getStatusCode(), HttpStatus.OK);
System.out.println("responseEntity: " + responseEntity.getBody());
}
@Test
public void webClientWithWireMockAsProxyServer() {
var client = HttpClient.create()
.tcpConfiguration(
tcpClient ->
tcpClient.proxy(
proxy -> {
proxy
.type(ProxyProvider.Proxy.HTTP)
.host(HOST)
.port(this.proxyServer.port());
}));
var webClient = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(client))
.build();
final var reqPatternBuilder =
RequestPatternBuilder.newRequestPattern(
RequestMethod.GET, WireMock.urlEqualTo(MOCK_ENDPOINT));
final var mappingBuilder =
WireMock.get(WireMock.urlEqualTo(reqPatternBuilder.build().getUrl()));
reqPatternBuilder
.withHeader(HttpHeaders.ACCEPT, WireMock.containing(MediaType.APPLICATION_JSON_VALUE))
.withHeader(
HttpHeaders.ACCEPT_CHARSET,
WireMock.containing(StandardCharsets.UTF_8.name().toUpperCase()));
mappingBuilder.willReturn(
WireMock.aResponse()
.withStatus(HttpStatus.OK.value())
.withBody("{ \"success\": true }")
.withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE));
this.targetWireMock.register(mappingBuilder);
var response =
webClient.get().uri(this.targetBaseUrl + MOCK_ENDPOINT).exchange().block().bodyToMono(String.class);
response.subscribe(x -> System.out.println("x:" + x));
}
}
Run Code Online (Sandbox Code Playgroud)
我抱怨错误java.net.UnknownHostException: <proxy server>: nodename nor servname provided, or not known。有没有办法模拟wiremock代理服务器,而不是为此运行实际的服务器。我还想将验证放在代理服务器中以进行请求响应。
Wiremock 不支持HTTP CONNECT 方法。您可以尝试使用Hoverfly作为 Wiremock 的替代品。如果您对详细信息感兴趣,可以查看github 问题。
| 归档时间: |
|
| 查看次数: |
840 次 |
| 最近记录: |