Назад к вопросам
Middle
368
questionbank

В чем заключается отличие между stop и mock?

Sobes Copilot

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

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

sobes.tech AI

stop — это техника изоляции теста от прямых зависимостей (например, обращений к сторонним API, базам данных) путем замены реальных объектов на тестовые заглушки. Он используется для контроля поведения внешних зависимостей и обеспечения воспроизводимости тестов.

mock (производное от "mock object") — это разновидность тестовой заглушки, которая не только заменяет реальный объект, но и позволяет проверять, как с ним взаимодействует тестируемый код. С помощью моков можно утверждать (assert) о вызовах методов, их аргументах и количестве вызовов.

Таким образом, stop - более общее понятие, описывающее изоляцию, а mock - конкретный инструмент для ее достижения, добавляющий возможность верификации взаимодействия.

Пример с использованием PHPUnit и Mockery:

<?php

use PHPUnit\Framework\TestCase;
use Mockery;

// Класс, использующий внешнюю зависимость
class UserProcessor
{
    private $apiClient;

    public function __construct(ApiClient $apiClient)
    {
        $this->apiClient = $apiClient;
    }

    public function processUserData(int $userId): bool
    {
        $data = $this->apiClient->fetchUserData($userId);

        if ($data && $data['status'] === 'active') {
            // Логика обработки активного пользователя
            return true;
        }
        return false;
    }
}

// Пример использования mock для тестирования
class UserProcessorTest extends TestCase
{
    public function testProcessUserDataWithActiveUser()
    {
        // Создаем мок для ApiClient
        $apiClientMock = Mockery::mock(ApiClient::class);

        // Задаем ожидаемое поведение для мока
        // Ожидаем вызов метода fetchUserData с аргументом 123
        $apiClientMock->shouldReceive('fetchUserData')
                      ->with(123)
                      ->andReturn(['status' => 'active', 'data' => '...']) // Мок возвращает эти данные
                      ->once(); // Ожидаем, что метод будет вызван ровно один раз

        // Создаем тестируемый объект, передавая ему мок
        $userProcessor = new UserProcessor($apiClientMock);

        // Выполняем тестируемый метод
        $result = $userProcessor->processUserData(123);

        // Проверяем результат
        $this->assertTrue($result);

        // Проверяем, что все ожидания мока были выполнены
        Mockery::close();
    }
}

В этом примере ApiClient заменяется "моком". Мы "заглушили" реальный вызов API и одновременно настроили мок на возврат определенных данных при вызове fetchUserData(123). Также мы верифицируем, что этот метод был вызван с правильными аргументами и один раз. Это и есть ключевое отличие: мок позволяет проверять взаимодействие.