Назад к вопросам
Junior
72
questionbank

Какие существуют виды тестовых объектов в контексте разработки программного обеспечения?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

В контексте разработки ПО используются следующие виды тестовых объектов:

  1. Дублер (Test Double): Общий термин для любого вида заменителя реального объекта, используемого в тестах.

  2. Заглушка (Stub): Объект, который возвращает предопределенные значения в ответ на вызовы методов. Используется для управления поведением зависимостей тестируемого объекта.

    // Пример Stub
    public class PaymentGatewayStub implements PaymentGateway {
        @Override
        public PaymentResult processPayment(PaymentDetails details) {
            // Всегда возвращаем успешный результат
            return new PaymentResult(true, "Success");
        }
    }
    
  3. Шпион (Spy): Частичный дублер. Оборачивает реальный объект, перехватывая вызовы методов для проверки, были ли они вызваны, сколько раз и с какими аргументами, но также может вызывать реальные методы.

    // Пример Spy using Mockito (популярная библиотека для создания тестовых объектов)
    // List<String> listSpy = Mockito.spy(new ArrayList<>());
    // listSpy.add("item");
    // verify(listSpy).add("item"); // Проверка вызова метода add
    
  4. Фальшивка (Fake): Объекты с работающей, но упрощенной реализацией. Например, in-memory база данных вместо реальной.

    // Пример Fake (простая in-memory реализация DAO)
    public class ProductDaoFake implements ProductDao {
        private Map<Long, Product> products = new HashMap<>();
        private long nextId = 1;
    
        @Override
        public void save(Product product) {
            if (product.getId() == null) {
                product.setId(nextId++);
            }
            products.put(product.getId(), product);
        }
    
        @Override
        public Product findById(Long id) {
            return products.get(id);
        }
    }
    
  5. Макет (Mock): Объекты, которые не только имитируют поведение, но и содержат предустановленные ожидания относительно вызовов методов. Должны "знать", как именно их должны вызывать в ходе теста. Если вызовы не соответствуют ожиданиям, тест проваливается.

    //Пример Mock using Mockito
    // MockMvc mockMvc = MockMvcBuilders.standaloneSetup(myController).build();
    // when(myService.getData()).thenReturn("test data"); // Ожидание вызова метода getData
    
    // mockMvc.perform(get("/api/data"))
    //        .andExpect(status().isOk())
    //        .andExpect(content().string("test data")); // Проверка результата
    // verify(myService).getData(); // Проверка, что метод getData был вызван
    

Основное различие между ними заключается в цели использования и уровне сложности имитации:

Вид Цель Поведение Проверка вызовов
Stub Предоставить предопределенные ответы Фиксированные ответы Нет
Spy Проверить вызовы методов реального объекта Имитирует часть поведения реального объекта (+ реальные методы) Да
Fake Упростить зависимость с работающей логикой Упрощенная, но работающая логика Обычно нет
Mock Проверить взаимодействие между объектами Предустановленные ожидания вызовов Да