Vytváření stub objektů pro mockování skutečných objektů.
Stub objekt patří do skupiny Double Test. Stub objekt používáme pro řešení závislostí na testovaném objektu, který v rámci závislosti požaduje objekt, který je složité sestavit a předat, nebo v rámci unit testů ani originální závislost použít nemůžeme.
Stub objekt je dvojníkem skutečného objektu, který obsahuje požadované funkční metody - tak jako objekt skutečný.
Stub objekt nám navíc dokáže říct, jaká jeho metoda byla zavolána.
####Vytvoření Stub objektu
Pro vytvoření Stub objektu je potřeba uvést název originálního objektu i s namespace, pokud je potřeba. Následně nadefinujem metody, její předpoklady a výchozí hodnoty, které má každá definovaná metoda vracet.
#####Základní definice Stub objektu
$stubian = new Stubian(Namespace\OriginClass');
Stub objekt bude typu \Namespace\OriginClass
#####Definice metody stub objektu
$stubian->foo()->andReturn(TRUE);
Stub objekt bude obsahovat metodu foo s návratovou hodnotou TRUE
#####Vytvoření stub objektu
$stub = $stubian->getStub();
Proměnná $stub nese objekt typu \Namespace\OriginClass, která obsahuje metodu foo - při jejím zavolání vrátí TRUE. Proměnnou $stub můžeme nyní předat jako závislost v rámci DI do testované třídy.
#####Ukázka Definice
public function setUp()
{
$stubian = new \Stubian('\Namespace\OriginClass');
$stubian->foo();
$stub = $stubian->getStub();
$this->tested_class = new \TestedClass($stub);
}
#####Základní definice metody foo
$stubian->foo();
#####Pro libovolné argumenty (včetně žádného) vrátí FALSE
$stubian->foo()->andReturn(FALSE);
#####Jen a pouze pro volání "foo(1, 3)" vrátí 4
$stubian->foo(1, 3)->andReturn(4);
#####Pro argument FALSE vrátí NULL
$stubian->foo(FALSE)->andReturn(NULL);
Vrácená hodnota může být libovoného typu, též výjimka nebo closura.
#####Vyhození výjimky při zavolání definované metody
$stubian->foo()->andReturn(new Exception);
#####Zpracování argumentů, se kterými byla definovaná metoda zavolána
$stubian->foo()->andReturn(function($a, $b){return $a + $b;});
#####Definice vrácené hodnoty pro libovoné argumenty
$stubian->foo()->andReturn(FALSE);
$stubian->foo(Stubian::WITH_ANY_ARGS)->andReturn(FALSE);
Oba zápisy jsou ekvivalentní. Naplnění konstantou WITH_ANY_ARGS je prováděno automaticky.
Tato definice vede k tomu, že pokud je metoda zavolána s libovolnými argumenty nebo zcela bez argumentů, je vráceno FALSE.
#####Definice vrácené hodnoty pro žádné argumenty
$stubian->foo(Stubian::WITH_NO_ARGS)->andReturn(TRUE);
#####Při vyhledávání hodnoty pro vrácení dochází nejprve k hledání v tomto pořadí:
- podle konstanty WITH_NO_ARGS
- podle zadaných argumentů
- podle konstanty WITH_ANY_ARGS
####Dodatečná změna návratové hodnoty u definované metody
Pokud potřebujete křížově otestovat metodu, která například obsahuje podmínku if musíte vždy u testované metody změnit vstupní parametr, nebo závislost, která podmínku ovlivňuje, tak aby podmínce bylo vyhověno a dostali jste se do další části podmínky.
#####Ukázka použití
Metoda s podmínkou if
public function foo()
{
if( $this->dependence === TRUE )
{
return TRUE;
}
else
{
return FALSE;
}
}
Definice závislosti v TestCase
public $stubian = NULL;
public $test_object = NULL;
public function setUp()
{
$this->stubian = new \Stubian('\Namespace\ExampleClass');
$this->stubian->dependence()->andReturn(TRUE);
$stub = $this->stubian->getStub();
$this->test_object = new \TestClass( $stub );
}
public function testFooTrue()
{
$this->assertTrue( $this->test_object->foo() );
}
Test nám prošel v pořádku, protože definovaná závislost obsahovala návratovou hodnotu TRUE. Nic méně, máme pokrytu pouze polovinu testované metody. Aby jsme pokryli zbylou část, musíme definované závislosti dependence změnit návratovou hodnotu, aby vracela cokoli jiného, než hodnotu TRUE.
public function testFooFalse()
{
$this->stubian->dependence()->andReturn(FALSE);
$this->assertFalse( $this->test_object->foo() );
}
Tím že jsme závislosti dependence přenastavili návratovou hodnotu na FALSE, tak jsme se dostali do další části testované metody.
#nevyhazoval bych vseobecnou vyjimku Exception
Pokud nebude dohledána návratová hodnota v žádném kroku, dojde k vyhození výjimky Stubian\Exception.
####Stub Objekt umožňuje získávat informace o volaných metodách
#####Vrátí počet volání metody foo()
$stubian->getSpy()->foo()->numberOfCalls();
#####NEVRÁTÍ
public function testSpocitejPocet()
{
$this->stub->getPocet(2)->andReturn(5);
$this->assertSame(5, $this->cigarko->spocitej_pocet(2), 'message');
$this->assertSame(5, $this->cigarko->spocitej_pocet(2), 'message');
var_dump($this->stub->getSpy()->getPocet()->paramsOfCall()); die();
}
1) Tests\AuthenticatorTest::testSpocitejPocet
Missing argument 1 for Stubian\Spy::paramsOfCall(), called in /Volumes/HTDOCS/mo-web/tests/case/unit/AuthenticatorTest.php on line 50 and defined
/Volumes/HTDOCS/mo-web/tests/libs/stubian/Stubian/Spy.php:59
/Volumes/HTDOCS/mo-web/tests/case/unit/AuthenticatorTest.php:50
#####Vrátí pole polí všech argumentů, s nimiž byla metoda volána
$stubian->getSpy()->foo()->paramsOfCall();
#####Vrátí pole argumentů, které byly předány při druhém volání
$stubian->getSpy()->foo()->paramsOfCall(2);