JUnit изменить класс или поведение метода в интеграционных тестах - PullRequest
3 голосов
/ 15 октября 2019

У меня есть Java-приложение (внутри Spring нет), которое я хочу протестировать с помощью интеграционного теста.

Мой основной сценарий использования - это основная функция, которая с указанным вводом выполняет некоторые действия в базе данных и отправляетнекоторые запросы к двум разным сервисам, одному SOAP и одному REST.

Теперь у меня есть рабочая конфигурация JUnit (разделенная на модульные и интеграционные тесты) + io.fabric8: docker-maven-plugin, использующий образ докера длябаза данных во время интеграционных тестов.

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

Большая проблема в том, что у меня есть эта структура:

class A{
    Result mainFunction(Request r){
        ....
        B b = new B(params);
        b.logEvent(someParameters)
        ....
    }
}
class B{
    int logEvent(Object someParameters){
        ....
        NotifierHandler nh = new NotifierHandler(param1);
        nh.sendNotification(json);
        ....
    }
}

, где у меня есть:

class NotifierHandler{
    String sendNotification(Json j){
        ...
        [call to REST service with some parameters]
        ...
        ...
        [call to SOAP service with some parameters]
        ...
    }
}

Что мне нужно : вызов A.mainFunction(r), имеющий вВ тестовой среде заменили NotifierHandler на FakeNotifierHandler и / или измените поведение метода sendNotification().

Актуальные проблемы : при использовании Mockito и PowerMock возникла проблемаЯ не могу изменить глобально и напрямую класс NotifierHandler с FakeNotifierHandler. То же самое, пытаясь изменить поведение метода.

В частности, мне нужно создать

class FakeNotifierHandler{
    String sendNotification(Json j){
        ...
        [save on an HashMap what I should send to the REST service]
        ...
        ...
        [save on another HashMap what I should send to the SOAP service]
        ...
    }
}

Читая все примеры, которые я пробовал, я видел только простые примеры, которые меняютвозвращаемое значение метода, а не поведение одного метода одного класса, используемого другим, и другого, который я использую в качестве начальной точки интеграционного теста.

ПРИМЕЧАНИЕ: вероятно, существует быстрый способ сделатьэто, но я очень новичок в этом типе тестов (Mockito, PowerMock, ...), и я не нашел примера для этого конкретного странного случая.

РЕДАКТИРОВАТЬ: не похоже на Как издеватьсяконструктор с PowerMockito , потому что мне нужно изменить поведение метода, а не только возвращаемое значение.

Заранее большое спасибо

1 Ответ

0 голосов
/ 15 октября 2019

Я думаю, что главная головная боль в вашем случае - это то, что у вас тесно связаны зависимости между классами A, B и NotifierHandler. Я хотел бы начать с:

class A {
  private B b;

  public A(B b) {
    this.b = b;
  }

  Result mainFunction(Request r){
      ....
      b.logEvent(someParameters)
      ....
  }
}
class B {
  private NotifierHandler nh;

  public B(NotifierHandler nh) {
    this.nh = nh;
  }

  int logEvent(Object someParameters){
      ....
      nh.sendNotification(json);
      ....
  }
}

Сделать NotifierHanlder интерфейсом:

interface NotifierHandler {
  String sendNotification(String json);
}

и сделать две реализации: одну для реального случая использования и одну фальшивку, которую вы можете заглушитьвсе, что вы хотите:

class FakeNotifierHandler implements NotifierHandler {

  @Override
  public String sendNotification(String json) {
    // whatever is needed for you
  }
}

Введите FakeNotifierHandler в свой тест.

Надеюсь, это поможет вам.

...