Java 单元测试用例Spring引导期间的模拟API调用

Java 单元测试用例Spring引导期间的模拟API调用,java,unit-testing,microservices,spring-boot-test,mockserver,Java,Unit Testing,Microservices,Spring Boot Test,Mockserver,我有两个微服务microservicea(上下文路径-/abc)和microserviceb(上下文路径-/def) URL示例:test.domain.com/abc/endpoint1、test.domain.com/def/endpoint2 在Microservice A(test.domain.com/abc/endpoint1)的一个API中,它在内部调用Microservice B(/def/endpoint2)->此内部调用的前缀生成如下 (从请求中提取域,然后追加/def/en

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

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

在Microservice A(test.domain.com/abc/endpoint1)的一个API中,它在内部调用Microservice B(/def/endpoint2)->此内部调用的前缀生成如下 (从请求中提取域,然后追加/def/endpoint2以进行rest调用,总url将变为(test.domain.com/def/endpoint2)

问题:当我们从控制器级别开始编写单元测试用例时,我们使用的是TestRestTemplate 对于此测试,我们需要使用http://localhost:要测试的端口号/abc/endpoint1

现在,def服务的url也将派生为http://localhost:端口号/def/endpoint2 如何模拟此响应(注意:我们不能在同一端口上使用模拟服务器,我们将得到端口绑定异常)。是否有解决方法

在使用TestRestTemplate进行路由时,有没有办法进行网关类型的设置http://localhost:portnumber/def/*调用以从mockserver和http://localhost:portnumber/abc/*要测试实际的API服务,可以使用
clienthttpprequestinterceptor
,并操作实际的
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;
    }
  }
}
然后,您可以为您的测试提供类型为
restemplatebuilder
的自定义bean,该bean由
testrestemplate
获取:

@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);
  }
}