Mockito @InjectMocks - Mocks 종속성 주입
Mockito @Spy 주석.
모키토 @InjectMocks
Mockito는 지정된 순서대로 세 가지 접근 방식 중 하나를 사용하여 모의 종속성을 주입하려고 시도합니다.
- 생성자 기반 주입 - 클래스에 대해 정의된 생성자가 있는 경우 Mockito는 가장 큰 생성자를 사용하여 종속성을 주입하려고 시도합니다.
- Setter 메소드 기반 - 정의된 생성자가 없을 때 Mockito는 setter 메소드를 사용하여 종속성을 주입하려고 시도합니다.
- 필드 기반 - 생성자나 필드 기반 주입이 가능하지 않은 경우 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;
}
}
종속성이 있는 App Service 클래스
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(this);
를 호출하지 않으면 JUnit 5 Tutorial을 얻게 됩니다.
@InjectMocks Setter 메소드 주입 예제
@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"));
}
GitHub 리포지토리에서 전체 코드와 더 많은 Mockito 예제를 확인할 수 있습니다.
참조: API 문서