Рубрики
Без рубрики

Mockito @InjectMocks – Издевается Над Инъекцией Зависимостей

Пример Mockito @InjectMocks, аргументы конструктора Mockito @InjectMocks, Исключение NullPointerException Mockito InjectMocks, Инъекция зависимостей Mockito InjectMocks

Автор оригинала: Pankaj Kumar.

Аннотации Mockito @InjectMocks позволяют нам вводить издевательские зависимости в аннотированный объект издевательства над классом. Это полезно, когда у нас есть внешние зависимости в классе, над которым мы хотим издеваться. Мы можем указать фиктивные объекты, которые будут введены, используя аннотации @Mock или @Spy.

Mockito @InjectMocks

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

  1. Инъекция на основе конструктора – когда для класса определен конструктор, Mockito пытается внедрить зависимости, используя самый большой конструктор.
  2. На основе методов настройки – когда не определены конструкторы, Mockito пытается внедрить зависимости с помощью методов настройки.
  3. На основе полей – если нет конструкторов или возможной инъекции на основе полей, то 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