Назад к вопросам
Middle
154
questionbank
Что такое Mock, Stab и Spy в контексте тестирования программного обеспечения?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
- Mock (Мок): Поддельный объект, который проверяет, что тестируемый код взаимодействует с ним ожидаемым образом (вызывает определенные методы, с определенными аргументами и в нужном порядке). Моки проверяют поведение.
- Stub (Стаб): Поддельный объект, который предоставляет заранее заданные ответы на вызовы методов. Стабы используются для управления состоянием зависимостей и фокусируются на тестируемом объекте, а не на взаимодействии с зависимостями. Стабы проверяют состояние.
- Spy (Шпион): Частично поддельный объект, который оборачивает реальный объект. Он позволяет отслеживать вызовы его методов (аргументы, количество вызовов и т.д.), при этом реальный метод может быть вызван. Шпионы хороши для проверки того, что реальный объект был использован, и при этом позволяют проверить его поведение.
| Тип | Основное назначение | Проверяет |
|---|---|---|
| Mock | Проверка взаимодействия | Поведение |
| Stub | Предоставление данных | Состояние |
| Spy | Отслеживание вызовов реального объекта | Поведение и состояние |
// Пример использования Mock с Mockito
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.mockito.Mockito.*;
public class ServiceTest {
@Mock
private Dependency dependencyMock;
private Service service;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
service = new Service(dependencyMock);
}
@Test
void shouldCallDependencyMethod() {
service.doSomething();
// Проверяем, что метод dependencyMethod был вызван один раз
verify(dependencyMock, times(1)).dependencyMethod();
}
}
class Service {
private final Dependency dependency;
public Service(Dependency dependency) {
this.dependency = dependency;
}
public void doSomething() {
dependency.dependencyMethod();
}
}
class Dependency {
public void dependencyMethod() {
// Реальная логика
}
public String getData() {
return "real data";
}
}
// Пример использования Stub с Mockito
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
public class AnotherServiceTest {
@Mock
private Dependency dependencyStub;
private AnotherService anotherService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
anotherService = new AnotherService(dependencyStub);
}
@Test
void shouldReturnStubbedData() {
// Задаем предопределенный ответ для метода getData()
when(dependencyStub.getData()).thenReturn("stubbed data");
String result = anotherService.processData();
// Проверяем, что сервис возвращает данные из стаба
assertEquals("processed stubbed data", result);
}
}
class AnotherService {
private final Dependency dependency;
public AnotherService(Dependency dependency) {
this.dependency = dependency;
}
public String processData() {
String data = dependency.getData();
return "processed " + data;
}
}
// Пример использования Spy с Mockito
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Spy;
import org.mockito.MockitoAnnotations;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class YetAnotherServiceTest {
@Spy
private Dependency dependencySpy = new Dependency(); // Шпионы оборачивают реальный объект
private YetAnotherService yetAnotherService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
yetAnotherService = new YetAnotherService(dependencySpy);
}
@Test
void shouldCallRealAndStubPartial() {
// Можно вызвать реальный метод
yetAnotherService.callSpyMethod();
// И проверить, что он был вызван
verify(dependencySpy, times(1)).dependencyMethod();
// Можно переопределить поведение для конкретного метода
when(dependencySpy.getData()).thenReturn("stubbed data for spy");
String result = yetAnotherService.getDataFromSpy();
// Проверяем, что вернулись переопределенные данные
assertEquals("stubbed data for spy", result);
// При этом можно проверить, что getData() был вызван
verify(dependencySpy, times(1)).getData();
}
}
class YetAnotherService {
private final Dependency dependency;
public YetAnotherService(Dependency dependency) {
this.dependency = dependency;
}
public void callSpyMethod() {
dependency.dependencyMethod();
}
public String getDataFromSpy() {
return dependency.getData();
}
}