微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Wiremock模拟正在运行的代理服务器

如何解决Wiremock模拟正在运行的代理服务器

我想为以下e2e场景添加测试:

我的应用正在通过内部代理服务器向外部服务发出Web请求,代理服务器操纵请求主体,将请求转发到目标主机并返回返回的响应。

例如 我对external.service/an/endpoint(通过my-proxy-server)尸体发出了发帖请求

{
"card_number": "<proxy server pls fill the cc details>"
}

代理服务器修改请求以填充抄送详细信息,并将其正文转发给external.service/an/endpoint

{
"card_number": "372735466563005"
}

external.service返回状态为OK。代理服务器返回响应而不进行修改

如何使用wiremock测试此工作流程?我可以为wiremock.stubFor()external.service,但是我不知道如何使wiremock代理与Webclient的代理设置一起工作。 实际看到该测试,其余模板测试,restTemplateWithwiremockAsProxyServer可以正常工作,通过代理路由我的请求,但是我的RCA出现了webClientWithwiremockAsProxyServer错误

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

无法通过here进行这些通过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,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));
  }

}

我抱怨错误java.net.UnkNownHostException: <proxy server>: nodename nor servname provided,or not kNown。有没有一种方法可以模拟wiremock代理服务器,而不是为此运行实际的服务器。我还想将验证放在代理服务器中以获取请求响应。

解决方法

Wiremock不支持HTTP CONNECT method。您可以尝试使用Hoverfly作为Wiremock的替代方法。如果您对详细信息感兴趣,则有a github issue

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。