Sobes.tech
Middle

Kuo skiriasi stop ir mock?

sobes.tech AI

Atsakymas iš AI

stop — tai technika, skirta izoliuoti testą nuo tiesioginių priklausomybių (pavyzdžiui, išorinių API skambučių, duomenų bazių) pakeičiant realius objektus testinėmis užuominomis. Ji naudojama siekiant kontroliuoti išorinių priklausomybių elgseną ir užtikrinti testų atkuriamumą.

mock (iš "mock object") — tai testinė užuomina, kuri ne tik pakeičia realų objektą, bet ir leidžia patikrinti, kaip su juo sąveikauja testuojamas kodas. Naudojant mock'us galima teigti (assert) apie metodų iškvietimus, jų argumentus ir iškvietimų skaičių.

Taigi, stop yra bendresnė sąvoka, apibūdinanti izoliaciją, o mock yra konkretus įrankis jos pasiekimui, pridedantis galimybę patikrinti sąveiką.

Pavyzdys naudojant PHPUnit ir Mockery:

<?php

use PHPUnit\Framework\TestCase;
use Mockery;

// Klasė, naudojanti išorinę priklausomybę
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') {
            // Aktyvaus naudotojo apdorojimo logika
            return true;
        }
        return false;
    }
}

// Pavyzdys naudojant mock testavimui
class UserProcessorTest extends TestCase
{
    public function testProcessUserDataWithActiveUser()
    {
        // Sukuriame mock `ApiClient`
        $apiClientMock = Mockery::mock(ApiClient::class);

        // Nustatome tikėtiną elgseną mock'e
        // Laukiame `fetchUserData` metodo iškvietimo su argumentu 123
        $apiClientMock->shouldReceive('fetchUserData')
                      ->with(123)
                      ->andReturn(['status' => 'active', 'data' => '...']) // Mock grąžina šiuos duomenis
                      ->once(); // Tikimės, kad metodas bus iškviestas tik vieną kartą

        // Sukuriame testuojamą objektą su mock
        $userProcessor = new UserProcessor($apiClientMock);

        // Vykdome testuojamą metodą
        $result = $userProcessor->processUserData(123);

        // Tikriname rezultatą
        $this->assertTrue($result);

        // Patvirtiname, kad visi mock'o lūkesčiai įvykdyti
        Mockery::close();
    }
}

Šiame pavyzdyje ApiClient pakeičiamas "moku". Mes "uždengėme" tikrą API skambutį ir kartu sukonfigūravome mock, kuris grąžins tam tikrus duomenis iškvietus fetchUserData(123). Taip pat patikriname, kad šis metodas buvo iškviestas su teisingais argumentais ir tik vieną kartą. Tai yra pagrindinis skirtumas: mock leidžia patikrinti sąveiką.