0

我有两个微服务微服务 A(上下文路径 - /abc)和微服务 B(上下文路径 - /def)

示例 URL:test.domain.com/abc/endpoint1 ,test.domain.com/def/endpoint2

在微服务 A (test.domain.com/abc/endpoint1) 的其中一个 API 中,它在内部调用微服务 B (/def/endpoint2) -> 此内部调用的前缀生成如下(从请求,然后附加 /def/endpoint2 进行休息调用,总 url 将变为 (test.domain.com/def/endpoint2)

问题:当我们从控制器级别开始编写单元测试用例时,我们正在使用 TestRestTemplate 对于这个测试,我们需要使用 http://localhost: portnumber /abc/endpoint1 来测试..

现在 def 服务的 url 也将导出为 http://localhost: portnumber /def/endpoint2 如何模拟这个响应(注意:我们不能在同一端口上使用模拟服务器,我们会得到端口绑定异常)。有没有相同的解决方法?

在使用 TestRestTemplate 路由 http://localhost:portnumber/def/* 调用以获取来自 mockserver 的响应和 http://localhost:portnumber/abc/* 以制作实际的 API 服务时,有没有办法进行网关类型的设置正在测试中?

4

1 回答 1

1

如果它与您的第二个微服务的路径匹配,您可以使用ClientHttpRequestInterceptor它并操纵实际URI调用。

这可能是一个天真的原型实现

public class UrlRewriter implements ClientHttpRequestInterceptor {
  @Override
  public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
    try {
      if (httpRequest.getURI().toString().contains("/def/abc")) {
        HttpRequest modifiedRequest = new MockClientHttpRequest(HttpMethod.GET, new URI("http://localhost:8888/def/abc"));
        return clientHttpRequestExecution.execute(modifiedRequest, bytes);
      } else {
        return clientHttpRequestExecution.execute(httpRequest, bytes);
      }

    } catch (URISyntaxException e) {
      e.printStackTrace();
      return null;
    }
  }
}

然后您可以RestTemplateBuilder为您的测试提供一个自定义类型的 bean,该 bean 由TestRestTemplate

@SpringBootTest(webEnvironment = RANDOM_PORT)
public class TestOne {


  @TestConfiguration
  static class TestConfig {

    @Bean
    public RestTemplateBuilder restTemplateBuilder() {
      return new RestTemplateBuilder().interceptors(new UrlRewriter());
    }

  }

  @Autowired
  private TestRestTemplate testRestTemplate;

  @Test
  public void test() {
    assertNotNull(testRestTemplate);

    testRestTemplate.getForObject("/abc/endpoint1", String.class);
  }
}
于 2020-08-07T19:21:07.557 回答