Поиск по сайту:

Мокито Учебник


Mockito — это фреймворк для имитации на основе Java, который используется в сочетании с другими фреймворками для тестирования, такими как Java Reflection API, и позволяет создавать объекты сервиса. Мок-объект возвращает фиктивные данные и избегает внешних зависимостей. Он упрощает разработку тестов, имитируя внешние зависимости и применяя макеты к тестируемому коду.

Мокито Учебник

Для руководства по Mockito мы будем использовать JUnit 5 и создадим несколько сервисов для имитации.

Зависимости Mockito Maven

Чтобы реализовать тестовые случаи на основе Mockito в проекте, добавьте следующую зависимость в файл pom.xml проекта:

<dependency>
     <groupId>org.mockito</groupId>
     <artifactId>mockito-core</artifactId>
     <version>2.19.0</version>
     <scope>test</scope>
</dependency>
<dependency>
     <groupId>org.mockito</groupId>
     <artifactId>mockito-junit-jupiter</artifactId>
     <version>2.19.0</version>
     <scope>test</scope>
</dependency>

Обратите внимание, что для JUnit 5 требуется mockito-junit-jupiter. Если вы используете любую другую среду тестирования, такую как JUnit 4 или TestNG, вы удаляете эту зависимость и включаете только mockito-core зависимость.

Мокито Мокап Создание

Платформа Mockito позволяет нам создавать фиктивные объекты, используя либо аннотацию @Mock, либо статический метод mock().

Метод mockito mock()

В приведенном ниже примере показано использование метода mock():

package com.journaldev.mockito;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import com.journaldev.AddService;
import com.journaldev.CalcService;

public class CalcService1Test {

	@Test
	void testCalc() {
		System.out.println("**--- Test testCalc executed ---**");

		AddService addService;
		CalcService calcService;

		addService = Mockito.mock(AddService.class);
		calcService = new CalcService(addService);

		int num1 = 11;
		int num2 = 12;
		int expected = 23;

		when(addService.add(num1, num2)).thenReturn(expected);

		int actual = calcService.calc(num1, num2);

		assertEquals(expected, actual);

	}
}

В приведенном выше примере мы тестируем CalcService. Метод Mockito.mock() используется для создания фиктивного объекта класса AddService.

Mockito Психологическая аннотация

В приведенном ниже примере показано использование аннотации @Mock.

package com.journaldev.mockito;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import com.journaldev.AddService;
import com.journaldev.CalcService;

public class CalcService2Test {

	CalcService calcService;

	@Mock
	AddService addService;

	@BeforeEach
	public void setup() {
		MockitoAnnotations.initMocks(this);
	}

	@Test
	public void testCalc() {
		System.out.println("**--- Test testCalc executed ---**");

		calcService = new CalcService(addService);

		int num1 = 11;
		int num2 = 12;
		int expected = 23;

		when(addService.add(num1, num2)).thenReturn(expected);

		int actual = calcService.calc(num1, num2);

		assertEquals(expected, actual);

	}
}

Обратите внимание, что нам нужно вызвать MockitoAnnotations.initMocks(this); для инициализации объектов, аннотированных с помощью @InjectMocks.

Проверка поведения Mockito

Чтобы добавить поведение в фиктивный класс, используются функции when() и thenReturn(). Это означает, что когда фиктивный объект (addService) вызывается для метода добавления с параметрами (num1, num2), он возвращает значение, хранящееся в ожидаемой переменной. Наш класс CalcService выглядит следующим образом:

public class CalcService {
	
	private AddService addService;
	
	public CalcService(AddService addService) {
		this.addService = addService;
	}

	public int calc(int num1, int num2) {
		System.out.println("**--- CalcService calc executed ---**");
		return addService.add(num1, num2);
	}

}

CalcService зависит от класса AddService. Он использует метод add класса AddService для выполнения своей операции. Поскольку мы хотели провести модульное тестирование только класса CalcService, нам нужно смоделировать экземпляр AddService. AddService выглядит следующим образом:

public interface AddService {
	public int add(int num1, int num2);
}
public class AddServiceImpl implements AddService {
	@Override
	public int add(int num1, int num2) {
		System.out.println("**--- AddServiceImpl add executed ---**");
		return num1 + num2;
	}
}

Mockito Проверка взаимодействия

Платформа Mockito отслеживает все вызовы методов и их параметры для фиктивного объекта. Метод Mockito verify() для фиктивного объекта проверяет, вызывается ли метод с определенными параметрами. Мы также можем указать количество логики вызова, например точное количество раз, по крайней мере указанное количество раз, меньше указанного количества раз и т. д. Мы можем использовать VerificationModeFactory для количества вызовов. логика раз. Метод Mockito verify() проверяет, вызывается ли метод с правильными параметрами. Он не проверяет результат вызова метода, такого как метод assert. В приведенном ниже примере демонстрируется использование метода verify():

package com.journaldev.mockito;

import static org.mockito.Mockito.verify;

import java.util.List;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.mockito.internal.verification.VerificationModeFactory;

public class VerifyInteractionTest {
	@Test
	public void testMethod() {
		@SuppressWarnings("unchecked")
		List<String> mockedList = Mockito.mock(List.class);

		mockedList.add("first-element");
		mockedList.add("second-element");
		mockedList.add("third-element");
		mockedList.add("third-element");
		mockedList.clear();

		verify(mockedList).add("first-element");
		verify(mockedList).add("second-element");
		verify(mockedList, VerificationModeFactory.times(2)).add("third-element");

		verify(mockedList).clear();
	}

}

Бетонный класс Mockito Stub

Используя функцию when() - thenReturn(), мы можем заглушить конкретный класс/класс реализации, а также один элемент коллекции. Элементы без заглушек будут содержать в себе null.

package com.journaldev.mockito;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class MockSingleElementTest {
	@SuppressWarnings("unchecked")
	@Test
	public void testMethod() {
		ArrayList mockedList = mock(ArrayList.class);

		when(mockedList.get(0)).thenReturn("first-element");

		System.out.println(mockedList.get(0));
		assertEquals("first-element", mockedList.get(0));
		
		// "null" gets printed as get(1) is not stubbed
		System.out.println(mockedList.get(1));
	}

}

Мокито шпион

Когда вы вызываете метод объекта-шпиона, будет вызываться настоящий метод, если не было определено предопределенное поведение. Используя spy, мы можем определить поведение, используя функции when() - theReturn() или вызвать реальную реализацию.

package com.journaldev.mockito;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

public class MockitoSpyTest {

	@Test
	public void testMethod() {
		List<String> list = new ArrayList<>();
		List<String> listSpy = spy(list);

		listSpy.add("first-element");
		System.out.println(listSpy.get(0));

		assertEquals("first-element", listSpy.get(0));
		when(listSpy.get(0)).thenReturn("second-element");
		System.out.println(listSpy.get(0));
		assertEquals("second-element", listSpy.get(0));
	}

}

Заключение

Mockito — популярный фреймворк для модульного тестирования Java. Мы можем легко имитировать зависимости, используя Mockito. Стиль кодирования Mockito свободный и похож на фреймворки JUnit и TestNG, поэтому его кривая обучения очень мала.

Вы можете загрузить полный код проекта из нашего репозитория GitHub.