Макет метода для нового экземпляра

#java #mockito #junit5

Вопрос:

Я пытаюсь создать тестовый случай Junit, используя платформу Mockito и junit5. Я работаю над приведенным ниже кодом:

     Class ClasstToBeTested {
      FirstClass a = new FirstClass();

      public String methodToBeTested() {
         String str = a.firstMethod();
         return str;
      }
    }

   Class FirstClass {
      SecondClass b = new SecondClass();

      public String firstMethod() {
          String str = b.secondMethod();
          return str;
      }
   }
 

У меня есть структура классов, как описано выше, и мне нужно поиздеваться над вторым методом.

Я попробовал @шпионить за первым классом и издевался над вторым классом и вторым методом, но насмешек не произошло. Как я могу издеваться в этом случае?

Примечание — я не в состоянии изменить структуру класса.

Комментарии:

1. можете ли вы изменить структуру своих классов? издевательство таким образом не сработает, по крайней мере, с Mockito .

2. Они являются наследием, я не смогу изменить структуру классов. Что — нибудь связанное с Пауэрмоком ?

3. да, загляни в PowerMock::whenNew

Ответ №1:

У вас есть несколько вариантов:

  1. (Предпочтительно) Используйте внедрение зависимостей IoC для предоставления SecondClass экземпляра вместо его создания внутри FirstClass :
   class FirstClass {
      private final SecondClass b;

      // Injecting the SecondClass instance
      FistClass(SecondClass b) {
          this.b = b;
      }

      public String firstMethod() {
          String str = b.secondMethod();
          return str;
      }
   }
 

Затем вы можете просто ввести макет в свой тест.

  1. Добавьте SecondClass сеттер только для тестов.
    class FirstClass {
      SecondClass b = new SecondClass();

      // Annotate with a visibility for test annotation if available.
      // Here one can inject a mock too, but can cause problems if used inadvertently.
      void setSecondClassForTests(SecondClass b) {
         this.b = b;
      }

      public String firstMethod() {
          String str = b.secondMethod();
          return str;
      }
   }
 

Затем вы вызываете сеттера на тест и передаете макет.

  1. Используйте отражение, чтобы получить поле и установить макет. Что-то вроде (В вашей тестовой функции):
 final Field declaredField = instanceOfFirstClass.getClass().getDeclaredFields("b");
declaredField.setAccessible(true);
declaredField.set(instanceOfFirstClass, yourMockedInstance);