繁体   English   中英

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

[英]Mock API calls During Unit Test cases Spring boot

我有两个微服务微服务 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) -> 此内部调用的前缀生成如下(从请求然后 append /def/endpoint2 进行 rest 调用,总 url 将变为(test.domain.com/def/endpoint2)

问题:当我们从 controller 级别开始编写单元测试用例时,我们正在使用 TestRestTemplate 对于此测试,我们需要使用 http://localhost: portnumber /abc/endpoint1 进行测试。

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

在使用 TestRestTemplate 路由 http://localhost:portnumber/def/* 调用以获取来自模拟服务器的响应和 http://localhost:portnumber/abc/* 以制作实际的 ZDB973442387108CACE146正在测试中?

可以为此使用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;
    }
  }
}

然后,您可以为TestRestTemplate拾取的测试提供类型为RestTemplateBuilder的自定义 bean:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM