Разница между @Mock и @InjectMocks в Mockito

Опубликовано: 18 Сентября, 2022

Mockito — это среда тестирования с открытым исходным кодом, используемая для модульного тестирования приложений Java. Он играет жизненно важную роль в разработке тестируемых приложений. Mockito используется для имитации интерфейсов, чтобы можно было добавить фиктивную функциональность к фиктивному интерфейсу, который можно использовать в модульном тестировании. Модульное тестирование — это тип тестирования программного обеспечения, при котором тестируются отдельные программные компоненты. Основная цель использования фреймворка Mockito — упростить разработку теста, имитируя внешние зависимости и используя их в тестовом коде. В результате Mockito предоставляет более простой тестовый код, более понятный, читабельный и модифицируемый. Mockito также можно использовать с другими средами тестирования, такими как JUnit и TestNG. Итак, в этой статье мы обсудим различия между @Mock и @InjectMocks , которые являются двумя наиболее важными и запутанными аннотациями, доступными в среде Mockito.

Главное отличие

Если говорить о главном отличии, то простыми словами можно сказать

@Mock creates a mock, and @InjectMocks creates an instance of the class and injects the mocks that are created with the @Mock annotations into this instance.

Давайте разберем приведенное выше утверждение на простом примере в Java .

Поймите разницу на примере

Предположим, у нас есть два класса с именами Student и Pen . И код для обоих этих классов выглядит следующим образом

Класс Student.java:

Java




class Student {
  
    private Pen pen;
  
    public Student(Pen pen) {
        this.pen = pen;
    }
  
    public String write() {
        return "Student Write with: " + pen.getRedPen();
    }
  
}

Класс Pen.java:

Java




class Pen {
  
    private String redPen;
  
    public Pen(String redPen) {
        this.redPen = redPen;
    }
  
    String getRedPen() {
        return redPen;
    }
}

Из приведенного выше кода видно, что классу Student требуется Pen для выполнения операции записи . Теперь давайте проведем модульное тестирование для класса Student.java .

Класс StudentTest.java:

Java




@RunWith(MockitoJUnitRunner.class)
class StudentTest {
  
    @Mock
    Pen pen;
  
    @InjectMocks
    Student student;
  
    @Test
    public void writeWithPenTest() throws Exception {
        Mockito.when(pen.getRedPen()).thenReturn("Red Pen");
        assertEquals("Student Write with: Red Pen", student.write());
    }
  
}

Итак, что происходит в коде, так это то, что Mockito будет имитировать класс Pen и его поведение, используя метод when и thenReturn . И, наконец, использование @InjectMocks Mockito поместит эту ручку в класс Student. И еще одна вещь, которую вы можете заметить, это то, что вам даже не нужно создавать новый объект Student. Mockito введет его для вас.

// we don"t have to do this
Student student = new Student(pen);

Таблица различий

@Насмехаться

@InjectMocks

@Mock создает макет. @InjectMocks создает экземпляр класса и внедряет макеты, созданные с помощью аннотаций @Mock, в этот экземпляр.
@Mock используется для создания макетов, необходимых для поддержки тестирования тестируемого класса. @InjectMocks используется для создания экземпляров класса, которые необходимо протестировать в тестовом классе.
Аннотированный класс для тестирования зависимостей с аннотацией @Mock. @InjectMocks используется, когда для данного класса необходимо выполнить фактическое тело метода.
Мы должны определить методы when-thenReturn для фиктивных объектов и какие методы класса будут вызываться во время фактического выполнения теста. Используйте @InjectMocks, когда нам нужно, чтобы все внутренние зависимости были инициализированы фиктивными объектами для правильной работы метода.