Mokka PHP Mocking Framework¶
Index¶
Installation¶
Composer¶
belanur/mokka kann einfach zur composer.json des Projekts hinzugefügt werden. Die aktuelle Version erhält man mit “dev-master”:
{
"require-dev": {
"belanur/mokka": "dev-master"
}
}
Aktuellen Quellcode auschecken¶
Der Mokka Quellcode ist auf GitHub verfügbar. Der Branch master sollte in den meisten Fällen verwendet werden.
$ git clone https://github.com/belanur/mokka
Cloning into 'mokka'...
remote: Counting objects: 745, done.
remote: Compressing objects: 100% (107/107), done.
remote: Total 745 (delta 59), reused 0 (delta 0)
Receiving objects: 100% (745/745), 101.76 KiB | 0 bytes/s, done.
Resolving deltas: 100% (395/395), done.
Checking connectivity... done
$
Um an Mokka mitzuarbeiten, sollte ein Fork erzeugt werden!
Mocks erzeugen¶
Mocks werden mit Mokka::mock() unter Angabe des Namens der Klasse, die gemockt werden soll, erzeugt.Ab PHP 5.5 kann dafür das ‘class’ Schlüsselwort verwendet werden,was wegen des besseren Refactoring-Supports empfohlen wird.
<?php
$mock = Mokka::mock(SampleClass::class);
Mit PHP 5.4 (die minimale Version, mit der Mokka funktioniert) muss der Klassenname als String übergeben werden
<?php
$mock = Mokka::mock('SampleClass');
Diese Methode hat den großen Nachteil, dass IDEs den String nicht als Klassennamen erkennen.Dadurch muss der Test manuell korrigiert werden, wenn ‘SampleClass’ mit einem Refactoring-Tool umbenannt wird.
Mocken¶
Via Mocking kann sichergestellt werden, dass eine Methode mit den vorgegebenen Argumenten aufgerufen wurde.
<?php
$mock = Mokka::mock(SampleClass::class);
// Verify sure that the method getBar() gets called once
Mokka::verify($mock)->getBar();
An Mokka::verify() kann optional eine Invokation Rule übergeben werden:
<?php
// Verify sure that the method getBar() is never called
Mokka::verify($mock, Mokka::never())->getBar();
// Make sure getBar() gets called at least twice
Mokka::verify($mock, Mokka::atLeast(2)->getBar();
// Make sure getBar() gets called exactly three times
Mokka::verify($mock, Mokka::exactly(3)->getBar();
Eine Methode kann mehrfach mit unterschiedlichen Argumenten gemockt werden:
<?php
// Make sure getBar() gets called once with the argument 'foo' and once with argument 'bar'
Mokka::verify($mock)->getBar('foo');
Mokka::verify($mock)->getBar('bar');
AnythingArgument¶
Mit dem AnythingArgument ist es nicht nötig, jedes einzelne Argument vorzugeben.
<?php
// Make sure getBar() gets called with the second argument 'foo'. The first argument can be anything.
Mokka::verify($mock)->getBar(Mokka::anything(), 'foo');
Stubben¶
Mit dem Stubben kann der Rückgabewert einer Methode vorgegeben werden.Eine gestubbte Methode hat keine Invokation Rule (wie gemockte Methoden). Wird eine gestubbte Methode nicht aufgerufen, wird folglich keine Exception geworfen.
<?php
$mock = Mokka::mock(SampleClass::class);
// getFoo() should return 'baz' when called with the argument 'bar'
Mokka::when($mock)->getFoo('bar')->thenReturn('baz');
echo $mock->getFoo(): // => NULL
echo $mock->getFoo('bar'); // => 'baz'
Hier kann auch das in Mocken eingeführte AnythingArgument verwendert werden:
<?php
// getFoo() should always return 'baz'
Mokka::when($mock)->getFoo(Mokka::anything())->thenReturn('baz');
echo $mock->getFoo('foo'): // => 'baz'
echo $mock->getFoo('bar'); // => 'baz'
Stubs und Mocks kombinieren¶
Mocks und Stubs können kombiniert werden, um einen Rückgabewert zu setzen und zusätzlich sicherzustellen, dass die Methode aufgerufen wird:
<?php
$mock = Mokka::mock(SampleClass::class);
// getFoo() should return 'baz' when called with the argument 'bar'
Mokka::when($mock)->getFoo('bar')->thenReturn('baz');
// also make sure that getFoo() gets called once
Mokka::verify($mock)->getFoo('bar');
echo $mock->getFoo('bar'); // => 'baz'
Exceptions werfen¶
Eine gestubbte Methode kann eine Exception werfen, anstatt einen Wert zurückzugeben:
<?php
$mock = Mokka::mock(SampleClass::class);
Mokka::when($mock)->getFoo()->thenThrow(new \InvalidArgumentException());
$mock->getBar(); // => throws exception
Mokka mit PHPUnit¶
Mokka bringt die Klasse MokkaTestCase mit, die einfachen Zugriff auf die Mokka-Funktionen bietet und zusätzlichen Support für PHPUnit bereitstellt.
<?php
class FooTest extends MokkaTestCase
{
public function testFoo()
{
$mock = $this->mock(SampleClass::class);
$foo = new Foo($mock);
}
}