简体   繁体   English

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

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

I have two microservices Microservice A ( context path - /abc ) and microservice B (context path - /def )我有两个微服务微服务 A(上下文路径 - /abc)和微服务 B(上下文路径 - /def)

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

In one of the apis of Microservice A ( test.domain.com/abc/endpoint1) internally its making call to Microservice B (/def/endpoint2) -> the prefix for this internal call is generated as follows (Extract the domain from the request and then append /def/endpoint2 to make a rest call the total url will become as (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)

Problem: When we are writting unit test cases starting controller level we are using TestRestTemplate For this testing we need to use http://localhost: portnumber /abc/endpoint1 to test..问题:当我们从 controller 级别开始编写单元测试用例时,我们正在使用 TestRestTemplate 对于此测试,我们需要使用 http://localhost: portnumber /abc/endpoint1 进行测试。

Now the url of the def service also will be derived as http://localhost: portnumber /def/endpoint2 How to mock this response ( Note: We cannot use mock server on same port, we will get port binding exception).现在 def 服务的 url 也将导出为 http://localhost: portnumber /def/endpoint2 如何模拟这个响应(注意:我们不能在同一端口上使用模拟服务器,我们会得到端口绑定异常)。 Is there any workaround for the same?有没有相同的解决方法?

Is there any way to have gateway kind of setup while using TestRestTemplate to route http://localhost:portnumber/def/* calls to get response from mockserver and http://localhost:portnumber/abc/* to make the actual API Service under test?在使用 TestRestTemplate 路由 http://localhost:portnumber/def/* 调用以获取来自模拟服务器的响应和 http://localhost:portnumber/abc/* 以制作实际的 ZDB973442387108CACE146正在测试中?

You could use a ClientHttpRequestInterceptor for this and manipulate the actual URI to call if it matches the path of your second microservice.可以为此使用ClientHttpRequestInterceptor并操作要调用的实际URI (如果它与您的第二个微服务的路径匹配)。

This might be a naive protoypish implementation :这可能是一个天真的原型实现

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

And then you can provide a custom bean of type RestTemplateBuilder for your test that is picked up by the TestRestTemplate :然后,您可以为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