Start · Sprachen · PHP · Referenz · uopz_set_mock

uopz_set_mock

Funktion

Ersetzt eine Klasse durch einen Mock, sodass <code>new ClassName</code> fortan eine Instanz des Mocks zurückgibt.

seit PHP 5.0.0 Kategorie: misc

Signatur

uopz_set_mock(string $class, mixed $mock): void

Beschreibung

uopz_set_mock() gehört zur UOPZ-Extension (User Operations for Zend) und ermöglicht es, eine bestehende Klasse durch einen Mock zu ersetzen. Alle nachfolgenden Instanziierungen der angegebenen Klasse via new $class liefern stattdessen Instanzen des Mocks — ohne den Quellcode der zu testenden Klasse ändern zu müssen.

Als Mock kann entweder ein Klassenname (String) oder ein bereits instanziiertes Objekt übergeben werden. Übergibt man einen Klassennamen, wird bei jedem new-Aufruf eine neue Instanz dieser Mock-Klasse erzeugt. Übergibt man ein Objekt, wird dieses Objekt jedes Mal zurückgegeben.

Die Funktion ist primär für Unit-Tests gedacht, in denen Abhängigkeiten (z. B. Datenbankverbindungen, HTTP-Clients, externe Dienste) durch kontrollierte Dummy-Implementierungen ersetzt werden sollen, ohne Dependency-Injection nutzen zu müssen oder den produktiven Code anzupassen.

Mocks werden mit uopz_unset_mock() wieder entfernt. Es empfiehlt sich, dies in der tearDown()-Methode von PHPUnit zu tun, um unerwünschte Seiteneffekte auf andere Tests zu vermeiden.

Parameter

Name Typ Default Beschreibung
$class Pflicht string Der vollständige Name der Klasse (inkl. Namespace), die durch den Mock ersetzt werden soll.
$mock Pflicht string|object Entweder der Name einer Mock-Klasse (String) oder ein bereits erstelltes Mock-Objekt. Bei einem Klassennamen wird bei jedem new-Aufruf eine neue Instanz erzeugt; bei einem Objekt wird immer dasselbe Objekt zurückgegeben.

Rückgabewert

Typ
void
Beschreibung
Gibt keinen Wert zurück.

Beispiele

Klasse durch Mock-Klassenname ersetzen

<?php
// Originale Klasse (z. B. ein externer HTTP-Client)
class HttpClient {
    public function get(string $url): string {
        return file_get_contents($url); // echter Netzwerkaufruf
    }
}

// Mock-Klasse für Tests
class MockHttpClient {
    public function get(string $url): string {
        return '{"status":"ok"}'; // simulierte Antwort
    }
}

// Mock aktivieren
uopz_set_mock('HttpClient', 'MockHttpClient');

$client = new HttpClient();
echo $client->get('https://beispiel.de/api'); // gibt den Mock-Wert zurück

// Mock nach dem Test wieder entfernen
uopz_unset_mock('HttpClient');
{"status":"ok"}

Klasse durch vorhandenes Objekt ersetzen

<?php
class Logger {
    public function log(string $message): void {
        file_put_contents('/var/log/app.log', $message . PHP_EOL, FILE_APPEND);
    }
}

class MockLogger {
    public array $messages = [];

    public function log(string $message): void {
        $this->messages[] = $message; // nur im Speicher festhalten
    }
}

$mockInstance = new MockLogger();
uopz_set_mock('Logger', $mockInstance);

$logger = new Logger(); // liefert $mockInstance zurück
$logger->log('Testmeldung');

var_dump($mockInstance->messages);

uopz_unset_mock('Logger');
array(1) { [0]=> string(12) "Testmeldung" }

// Wichtig · Fallstricke

Achtung: uopz_set_mock() ist ausschließlich für Testumgebungen gedacht und sollte niemals in Produktionscode eingesetzt werden. Die UOPZ-Extension verändert das Laufzeitverhalten der Zend Engine und kann bei unsachgemäßem Einsatz zu schwer nachvollziehbaren Fehlern führen.

Die Funktion setzt voraus, dass die UOPZ-Extension installiert und geladen ist (extension=uopz in der php.ini). Sie ist nicht Teil der PHP-Standardinstallation.

Wird ein Mock-Objekt (statt eines Klassennamens) übergeben, ist zu beachten, dass alle new-Aufrufe auf dasselbe Objekt zeigen. Zustandsänderungen an dem Objekt sind daher in allen Stellen sichtbar, die es verwenden.

Ab UOPZ 6.x gibt es geringfügige Verhaltensänderungen bei der Behandlung von Namespaces. Klassenname immer vollständig und ohne führenden Backslash angeben.