Как я могу добавить аннотированное @ поле в RestEasy @Provider? - PullRequest
0 голосов
/ 10 апреля 2019

С RestEasy в контейнере JBoss у меня есть ExceptionMapper с аннотацией @Provider, которая имеет доступ к аннотациям HttpServletRequest и HttpServletResponse через @Context, например:

@Provider
public class MyExceptionMapper implements ExceptionMapper<Throwable> {
  @Context
  private HttpServletRequest httpServletRequest;

  @Context
  private HttpServletResponse httpServletResponse;

  @Override
  public Response toResponse(final Throwable exception) {
    ...
    return response;
  }
}

Я новичок в RestEasy, родом из Spring, поэтому наивно полагал, что смогу внедрить эти два поля и подделать их в модульном тесте, но это кажется сложнее, чем я ожидал!

В случае, если фреймворк уместен, я использую JMockit, и я тоже новичок в этом. До сих пор мне удавалось применить мои знания о Mockito с хорошим успехом.

Я не нахожу многого в поиске по теме, кроме множества предложений по запуску встроенного контейнера в моих модульных тестах. Я не полностью против этого, но мне кажется, что это излишне, когда я просто пытаюсь написать простой модульный тест.

Я попробовал несколько вещей в тесте, совсем недавно это:

public class MyExceptionMapperTest {
  @Injectable
  private HttpServletRequest httpServletRequest;

  @Injectable
  private HttpServletResponse httpServletResponse;

  @Tested
  private MyExceptionMapper exceptionMapper;

  @Test
  public void test() {
    exceptionMapper.toResponse(new Throwable());
  }
}

Но это приводит к NullPointerException в MyExceptionMapper при первом обращении к одному из полей @Context, которое говорит мне, что они не вводятся.

Я также пробовал:

  • с использованием @Mocked вместо @Injectable;
  • непосредственное создание экземпляра MyExceptionMapper как с аннотацией @Tested, так и без нее;
  • создает Expectations в моем тесте; и
  • каждая перестановка выше

Во всех случаях @Context -аннотированные поля имеют значение null.

Надеюсь, я просто упускаю что-то очень очевидное?

1 Ответ

0 голосов
/ 11 апреля 2019

В отсутствие лучшего ответа я использовал рефлексию в своих тестах, чтобы ввести значение для этих двух свойств.Не идеально, но это работает:

public class MyExceptionMapperTest {
  @Mocked
  private HttpServletRequest mockHttpServletRequest;

  @Mocked
  private HttpServletResponse mockHttpServletResponse;

  private MyExceptionMapper exceptionMapper = new MyExceptionMapper();

  @Before
  public void setup() {
    Field httpServletRequest = exceptionMapper.getClass().getDeclaredField("httpServletRequest");
    httpServletRequest.setAccessible(true);
    httpServletRequest.set(exceptionMapper, mockHttpServletRequest);

    Field httpServletResponse = exceptionMapper.getClass().getDeclaredField("httpServletResponse");
    httpServletResponse.setAccessible(true);
    httpServletResponse.set(exceptionMapper, mockHttpServletResponse);
  }
}

Затем в своих тестах я могу установить ожидания и проверки для двух значений @Mocked как нормальные.

Я не эксперт по рефлексии,так что это, вероятно, не самый лучший / самый эффективный подход, но он достаточно хорош для моих нужд.

...