Модульное тестирование doFilter для идентификатора корреляции - PullRequest
0 голосов
/ 07 октября 2018

Я работаю над сборкой приложения, используя dropwizard.

Я создал фильтр для перехвата и регистрации идентификатора корреляции вызывающей службы.

Если во входящем запросе нет заголовка «Correlation-Id» в заголовке, мы бы прикрепили его к ответу.

Ниже приведен фильтр:

public class CorrelationIdServletFilter implements Filter {

private static final Logger LOGGER =
  LoggerFactory.getLogger(CorrelationIdServletFilter.class);

 private static final String CORRELATION_ID_HEADER_NAME = "Correlation-ID";

 private static final String CORRELATION_ID_MDC_KEY = " ";

 private static final InheritableThreadLocal<String> correlationId =
  new InheritableThreadLocal<>();

  public static String getCorrelationId() {
return correlationId.get();
 }

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {}

 @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  throws IOException, ServletException {

try {
  HttpServletRequest req = (HttpServletRequest) request;

  HttpServletResponse res = (HttpServletResponse) response;

  String correlationIdHeaderValue = req.getHeader(CORRELATION_ID_HEADER_NAME);

  LOGGER.debug
      (
      "HTTP Header("
          + CORRELATION_ID_HEADER_NAME
          + ") = ["
          + correlationIdHeaderValue
          + "] will generate a new correlationId if incoming is NULL");

  String correlationIdRaw;

  if (!StringUtils.isEmpty(correlationIdHeaderValue)) {
    correlationIdRaw = correlationIdHeaderValue;
  } else {
    correlationIdRaw = UUID.randomUUID().toString();
  }

  LOGGER.debug("Request: (" + req.getRequestURI() + ") is marked as :" + correlationIdRaw);

  correlationId.set(correlationIdRaw);

  MDC.put(CORRELATION_ID_MDC_KEY, getCorrelationId());

  res.addHeader(CORRELATION_ID_HEADER_NAME, correlationIdRaw);

  LOGGER.debug(
      "Response holds correlationId : ("
          + res.getHeader("Correlation-ID")
          + ") in its header ");

  chain.doFilter(req, res);

} finally {
  correlationId.remove();
  MDC.remove(CORRELATION_ID_MDC_KEY);
}
}

  @Override
  public void destroy() {}
}

Мне нужно написать модульные тесты для двух случаев:

  1. Когда запрос отправляется без Id корреляции.Убедитесь, что идентификатор генерируется на стороне сервера.

  2. Когда отправляется ответ с идентификатором корреляции.Проверьте, что оно отправлено обратно с ответом.

Может кто-нибудь указать мне, как это можно сделать?

Я пытался использовать макет, но у меня нет ответа, в котором ничего нетheader.

@Test
  public void testResponse_for_RequestWithoutCcid() throws IOException, ServletException {

HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
FilterChain filterChain = mock(FilterChain.class);
CorrelationIdServletFilter CorrelationIdServletFilter = mock(
    CorrelationIdServletFilter.class);
CorrelationIdServletFilter.init(mock(FilterConfig.class));

CorrelationIdServletFilter.doFilter(httpServletRequest, httpServletResponse,
    filterChain);


System.out.println(httpServletResponse.getHeaderNames());

CorrelationIdServletFilter.destroy();

verify(CorrelationIdServletFilter, times(1))
    .doFilter(httpServletRequest, httpServletResponse, filterChain);

}

Есть ли способ сделать это?Любая помощь могла бы быть полезна.Есть ли способ это без насмешки?

1 Ответ

0 голосов
/ 07 октября 2018

Некоторые из основных проблем с тестом, который вы написали:

  1. Тестируемый класс никогда не подвергается проверке (могут быть некоторые исключения), потому что вы хотите сделать реальные вызовы для модульного тестирования различныхметоды тестируемого класса.
  2. Мы всегда должны писать отдельные модульные тесты для различных методов тестируемого класса.Здесь я вижу, что вы также вызываете методы init и destroy, которые не нужны, когда вы хотите протестировать метод doFilter.
  3. Когда мы создаем какие-либо фиктивные объекты, мы используем ожидания дляопределите вызовы, которые мы ожидаем сделать для фиктивных объектов, и пусть они возвращают некоторое заглушенное значение, если это необходимо.

Теперь я попытался написать правильный тест, который бы утверждал оба случая, которые вы хотитедля тестирования:

@Test
public void testResponse_for_RequestWithoutCcid() throws IOException, ServletException {

HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
FilterChain filterChain = mock(FilterChain.class);
CorrelationIdServletFilter correlationIdServletFilter = new CorrelationIdServletFilter();

expect(httpServletRequest.getHeader(CORRELATION_ID_HEADER_NAME)).andReturn(""); // Empty correlation id in the request

Capture capturedCorrelationIdRaw = newCapture();

httpServletResponse.addHeader(CORRELATION_ID_HEADER_NAME, capture(capturedCorrelationIdRaw));
expectLastCall(); // used for void methods in EasyMock framework

filterChain.doFilter(httpServletRequest, httpServletResponse);
expectLastCall();

CorrelationIdServletFilter.doFilter(httpServletRequest, httpServletResponse,
    filterChain);


assertNotEmpty(capturedCorrelationIdRaw.getValue());


verify(httpServletRequest, times(1))
    .getHeader(CORRELATION_ID_HEADER_NAME);
verify(httpServletResponse, times(1))
    .addHeader(CORRELATION_ID_HEADER_NAME, anyString);

}

Этот тест необходимо обновить в соответствии с используемой платформой тестирования, но я изо всех сил старался дать вам представление о том, как должен выглядеть тест.

...