Макетные вызовы API во время модульных тестов Spring boot - PullRequest
0 голосов
/ 06 августа 2020

У меня есть два микросервиса Microservice A (контекстный путь - / ab c) и микросервис B (контекстный путь - / def)

Примеры URL-адресов: test.domain.com/abc/endpoint1, test. domain.com/def/endpoint2

В одном из API-интерфейсов Microservice A (test.domain.com/abc/endpoint1) он выполняет внутренний вызов Microservice B (/ def / endpoint2) -> префикс для этот внутренний вызов генерируется следующим образом (извлеките домен из запроса, а затем добавьте / def / endpoint2, чтобы выполнить вызов отдыха, общий URL-адрес станет как (test.domain.com/def/endpoint2)

Проблема : Когда мы пишем модульные тесты, начиная с уровня контроллера, мы используем TestRestTemplate. Для этого тестирования нам нужно использовать http://localhost: номер порта / abc / endpoint1 для тестирования ..

Теперь URL службы def также будет получен как http://localhost: номер порта / def / endpoint2 Как имитировать этот ответ (Примечание: мы не можем использовать фиктивный сервер на том же порту, мы получим исключение привязки порта). там любая работа примерно так же?

Есть ли способ настроить тип шлюза при использовании TestRestTemplate для маршрутизации вызовов http://localhost: portnumber / def / * для получения ответа от mockserver и http://localhost: portnumber / abc / * для тестирования действующей службы API?

1 Ответ

1 голос
/ 07 августа 2020

Вы могли бы использовать для этого ClientHttpRequestInterceptor и манипулировать фактическим URI для вызова, если он соответствует пути вашего второго микросервиса.

Это может быть наивный protoypi sh реализация :

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

И затем вы можете предоставить настраиваемый bean-компонент типа RestTemplateBuilder для своего теста, который подбирается 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);
  }
}
...