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.