Автор оригинала: Pankaj Kumar.
Аннотации Mockito @InjectMocks позволяют нам вводить издевательские зависимости в аннотированный объект издевательства над классом. Это полезно, когда у нас есть внешние зависимости в классе, над которым мы хотим издеваться. Мы можем указать фиктивные объекты, которые будут введены, используя аннотации @Mock или @Spy.
Mockito @InjectMocks
Mockito пытается внедрить издевательские зависимости, используя один из трех подходов, в указанном порядке.
- Инъекция на основе конструктора – когда для класса определен конструктор, Mockito пытается внедрить зависимости, используя самый большой конструктор.
- На основе методов настройки – когда не определены конструкторы, Mockito пытается внедрить зависимости с помощью методов настройки.
- На основе полей – если нет конструкторов или возможной инъекции на основе полей, то mockito пытается внедрить зависимости в само поле.
Если есть только один соответствующий макет объекта, то mockito введет его в объект. Если существует более одного поддельного объекта одного и того же класса, то имя поддельного объекта используется для введения зависимостей.
Пример макета @InjectMocks
Давайте создадим некоторые службы и классы с зависимостями, чтобы мы могли видеть, как Mockito внедряет зависимости в действие.
Классы обслуживания
package com.journaldev.injectmocksservices;
public interface Service {
public boolean send(String msg);
}
package com.journaldev.injectmocksservices;
public class EmailService implements Service {
@Override
public boolean send(String msg) {
System.out.println("Sending email");
return true;
}
}
package com.journaldev.injectmocksservices;
public class SMSService implements Service {
@Override
public boolean send(String msg) {
System.out.println("Sending SMS");
return true;
}
}
Классы служб приложений с зависимостями
package com.journaldev.injectmocksservices;
//For Constructor Based @InjectMocks injection
public class AppServices {
private EmailService emailService;
private SMSService smsService;
public AppServices(EmailService emailService, SMSService smsService) {
this.emailService = emailService;
this.smsService = smsService;
}
public boolean sendSMS(String msg) {
return smsService.send(msg);
}
public boolean sendEmail(String msg) {
return emailService.send(msg);
}
}
package com.journaldev.injectmocksservices;
//For Property Setter Based @InjectMocks injection
public class AppServices1 {
private EmailService emailService;
private SMSService smsService;
public void setEmailService(EmailService emailService) {
this.emailService = emailService;
}
public void setSmsService(SMSService smsService) {
this.smsService = smsService;
}
public boolean sendSMS(String msg) {
return smsService.send(msg);
}
public boolean sendEmail(String msg) {
return emailService.send(msg);
}
}
package com.journaldev.injectmocksservices;
//For Field Based @InjectMocks injection
public class AppServices2 {
private EmailService emailService;
private SMSService smsService;
public boolean sendSMS(String msg) {
return smsService.send(msg);
}
public boolean sendEmail(String msg) {
return emailService.send(msg);
}
}
Пример Инъекции конструктора @InjectMocks
package com.journaldev.mockito.injectmocks;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import com.journaldev.injectmocksservices.AppServices;
import com.journaldev.injectmocksservices.AppServices1;
import com.journaldev.injectmocksservices.AppServices2;
import com.journaldev.injectmocksservices.EmailService;
import com.journaldev.injectmocksservices.SMSService;
class MockitoInjectMocksExamples extends BaseTestCase {
@Mock EmailService emailService;
@Mock SMSService smsService;
@InjectMocks AppServices appServicesConstructorInjectionMock;
@InjectMocks AppServices1 appServicesSetterInjectionMock;
@InjectMocks AppServices2 appServicesFieldInjectionMock;
@Test
void test_constructor_injection_mock() {
when(appServicesConstructorInjectionMock.sendEmail("Email")).thenReturn(true);
when(appServicesConstructorInjectionMock.sendSMS(anyString())).thenReturn(true);
assertTrue(appServicesConstructorInjectionMock.sendEmail("Email"));
assertFalse(appServicesConstructorInjectionMock.sendEmail("Unstubbed Email"));
assertTrue(appServicesConstructorInjectionMock.sendSMS("SMS"));
}
}
Вы заметили, что мой тестовый класс расширяется BaseTestCase . Это делается для инициализации насмешек Mockito перед тестами, вот код класса.
package com.journaldev.mockito.injectmocks;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.MockitoAnnotations;
class BaseTestCase {
@BeforeEach
void init_mocks() {
MockitoAnnotations.initMocks(this);
}
}
Если вы не будете вызывать MockitoAnnotations.initMocks(это); тогда вы получите Исключение NullPointerException .
Кроме того, я использую JUnit 5 для запуска тестовых случаев. Если вы не знакомы с ним, ознакомьтесь с руководством по JUnit 5 .
@InjectMocks Пример методов установки инъекций
@Test
void test_setter_injection_mock() {
when(appServicesSetterInjectionMock.sendEmail("New Email")).thenReturn(true);
when(appServicesSetterInjectionMock.sendSMS(anyString())).thenReturn(true);
assertTrue(appServicesSetterInjectionMock.sendEmail("New Email"));
assertFalse(appServicesSetterInjectionMock.sendEmail("Unstubbed Email"));
assertTrue(appServicesSetterInjectionMock.sendSMS("SMS"));
}
@InjectMocks Пример Инъекции На Основе поля
@Test
void test_field_injection_mock() {
when(appServicesFieldInjectionMock.sendEmail(anyString())).thenReturn(true);
when(appServicesFieldInjectionMock.sendSMS(anyString())).thenReturn(true);
assertTrue(appServicesFieldInjectionMock.sendEmail("Email"));
assertTrue(appServicesFieldInjectionMock.sendEmail("New Email"));
assertTrue(appServicesFieldInjectionMock.sendSMS("SMS"));
}
Ссылка: API Doc