Skip to content

Instantly share code, notes, and snippets.

@rdpanek
Created December 12, 2012 12:38
Show Gist options
  • Save rdpanek/4267429 to your computer and use it in GitHub Desktop.
Save rdpanek/4267429 to your computer and use it in GitHub Desktop.

Stubian

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

Možné definice metod v Stub Objektu

#####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í:

  1. podle konstanty WITH_NO_ARGS
  2. podle zadaných argumentů
  3. 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);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment