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);