Sobes.tech
Middle

Na czym polega różnica między stop a mock?

sobes.tech AI

Odpowiedź od AI

stop — to technika izolacji testu od bezpośrednich zależności (np. wywołań do zewnętrznych API, baz danych) poprzez zastąpienie rzeczywistych obiektów testowymi atrapami. Używa się jej do kontrolowania zachowania zewnętrznych zależności i zapewnienia powtarzalności testów.

mock (pochodzące od "mock object") — to rodzaj atrap testowych, które nie tylko zastępują rzeczywisty obiekt, ale także pozwalają na sprawdzanie, jak testowany kod z nim współdziała. Za pomocą mocków można stawiać (assert) tezy o wywołaniach metod, ich argumentach i liczbie wywołań.

Zatem, stop to bardziej ogólne pojęcie opisujące izolację, a mock to konkretny narzędzie do jej osiągnięcia, dodające możliwość weryfikacji interakcji.

Przykład z użyciem PHPUnit i Mockery:

<?php

use PHPUnit\Framework\TestCase;
use Mockery;

// Klasa korzystająca z zewnętrznej zależności
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') {
            // Logika obsługi aktywnego użytkownika
            return true;
        }
        return false;
    }
}

// Przykład użycia mocka do testowania
class UserProcessorTest extends TestCase
{
    public function testProcessUserDataWithActiveUser()
    {
        // Tworzymy mocka dla ApiClient
        $apiClientMock = Mockery::mock(ApiClient::class);

        // Ustawiamy oczekiwane zachowanie mocka
        // Oczekujemy wywołania metody fetchUserData z argumentem 123
        $apiClientMock->shouldReceive('fetchUserData')
                      ->with(123)
                      ->andReturn(['status' => 'active', 'data' => '...']) // Mock zwraca te dane
                      ->once(); // Oczekujemy, że metoda zostanie wywołana dokładnie raz

        // Tworzymy obiekt testowy, przekazując mu mocka
        $userProcessor = new UserProcessor($apiClientMock);

        // Wywołujemy testowaną metodę
        $result = $userProcessor->processUserData(123);

        // Sprawdzamy wynik
        $this->assertTrue($result);

        // Sprawdzamy, czy wszystkie oczekiwania mocka zostały spełnione
        Mockery::close();
    }
}

W tym przykładzie ApiClient jest zastępowany przez "mock". Zastąpiliśmy rzeczywiste wywołanie API i jednocześnie skonfigurowaliśmy mock tak, aby zwracał określone dane przy wywołaniu fetchUserData(123). Dodatkowo weryfikujemy, czy ten metod został wywołany z poprawnymi argumentami i dokładnie raz. To jest kluczowa różnica: mock pozwala na sprawdzanie interakcji.