Problem s mockovanim Nette\Security\IUserStorage

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
vitmichal
Člen | 6
+
0
-

Ahoj vsichni,

Zatim neuspesne se pokousim o testovani presenteru s pouzitim PHPUnit. Podle tohoto navodu jsem se pustil do mockovani tridy UserStorage, tak aby nepouzivala sessions:

<?php
use \Nette\Security\IUserStorage;
use \Nette;

class DummyUserStorage implements \Nette\Security\IUserStorage
{

    private $authenticated;

    private $identity;

    public function setAuthenticated($state)
    {
        $this->authenticated = $state;
    }

    public function isAuthenticated()
    {
        return $this->authenticated;
    }

    public function setIdentity(\Nette\Security\IUserStorage\IIdentity $identity = NULL)
    {
        $this->identity = $identity;
    }

    public function getIdentity()
    {
        return $this->identity;
    }

    public function setExpiration($time, $flags = 0)
    {
    }

    public function getLogoutReason()
    {
        return NULL;
    }

}
?>

A pak se ji znazim pouzivat v testovacim config.test.neonu:

nette:
    session:
        expiration: 10 days

    services:
        nette.userStorage:
            class: DummyUserStorage

Bohuzel kdyz spustim test:

./phpunit.phar --bootstrap ./presenter-test-bootstrap.php ./app/models/HomepageModule/presenters/HomepagePresenterTest.php

Tak mi to hodi vyjimku, ze mam spatne implementovanou metodu IUserStorage::setIdentity().

Fatal error: Declaration of DummyUserStorage::setIdentity() must be compatible with that of Nette\Security\IUserStorage::setIdentity() in /var/www/test/DummyUserStorage.php on line 6
exception 'Nette\FatalErrorException' with message 'Declaration of DummyUserStorage::setIdentity() must be compatible with that of Nette\Security\IUserStorage::setIdentity()' in /var/www/test/DummyUserStorage.php:6
Stack trace:
#0 [internal function]: Nette\Diagnostics\Debugger::_shutdownHandler()
#1 {main}
(stored in /var/www/log/exception-2014-02-11-11-00-28-8e6d4fb1c1ce4848ff65f575942c3766.html)

Pritom ta metoda je v rozhrani IUserStorage definovana takto:

<?php
41:     /**
42:      * Sets the user identity.
43:      * @return void
44:      */
45:     function setIdentity(IIdentity $identity = NULL);
46:

?>

Moje implementovana metoda vypada takhle:

<?php

    public function setIdentity(\Nette\Security\IUserStorage\IIdentity $identity = NULL)
    {
        $this->identity = $identity;
    }

?>

Napada vas, proc to hlasi chybu, ze je metoda spatne implementovana, kdyz je podle mne stejna jako v interfacu ?

David Matějka
Moderator | 6445
+
0
-

ten interface identity je \Nette\Security\IIdentity

Editoval matej21 (11. 2. 2014 12:12)

vitmichal
Člen | 6
+
0
-

Diky moc! Blby preklep :)

vitmichal
Člen | 6
+
0
-

Aby toho nebylo malo, mam tu dalsi zasek :)

Pujcil jsem si mock Nette\Http\Session od www.kdyby.org (diky :) a s bootstrapem:

<?php
define("DEBUG", true); // shows debgbar at right bottom of screen
define("XHPROF", DEBUG); // save profiling information into /tmp/xhprof and enable xhprof toolbar
define("POUPDATING", false); // inserting untranslated strings into .po file
define("LOGMISSINGTRANSLATION", false); // saves untranslated messages to file

// Load Nette Framework
$params['appDir'] = __DIR__ . '/../app';
$params['libsDir'] = __DIR__ . '/../libs';
$params['langDir'] = '%appDir%/../locale';
$params['lang'] = 'en';

require $params['libsDir'] . '/Nette-2.0.3/loader.php';


\Nette\Diagnostics\Debugger::enable(false);
\Nette\Diagnostics\Debugger::$strictMode = true;

// Load configuration from config.neon file
$configurator = new Nette\Config\Configurator;

// Enable Nette Debugger for error visualisation & logging
$configurator->setProductionMode(!DEBUG);
$configurator->enableDebugger(__DIR__ . '/../log');
$configurator->setTempDirectory(__DIR__ . '/../temp');
$robotloader = $configurator->createRobotLoader()->addDirectory(__DIR__)->addDirectory($params['appDir'])->addDirectory($params['libsDir'])->register();

// Create Dependency Injection container from config.neon file
$configurator->addConfig(__DIR__.'/config.test.neon');
$configurator->addParameters($params);


$container = $configurator->createContainer();
$container->addService('robotLoader', $robotloader);
$container->addService('container', $container);

$GLOBALS['container'] = $container;
?>

spoustim tento test:

<?php
use Nette\Application\Request;

class HomepagePresenterTest extends BaseTestCase
{

    public function testHomepage()
    {
        // získám správný presenter
        $presenter = $this->getPresenter('Homepage:Homepage');

        // vytvořím request
        $request = new Request('HomepageModule:Homepage', 'GET', array( ));

        // spustím request
        $response = $presenter->run($request);

        // zkontroluji response
        $this->assertInstanceOf('Nette\Application\Responses\TextResponse', $response);
        $template = $response->getSource();
        $this->assertEquals('Lorem ipsum', $template->title);
    }

}
?>

A jako vysledek dostanu:

Fatal error: Call to a member function storeRequest() on a non-object in /var/www/libs/Nette-2.0.3/loader.php on line 1151
exception 'Nette\FatalErrorException' with message 'Call to a member function storeRequest() on a non-object' in /var/www/libs/Nette-2.0.3/loader.php:1151
Stack trace:
#0 [internal function]: Nette\Diagnostics\Debugger::_shutdownHandler()
#1 {main}

Coz asi znamena, ze $this->presenter neni vyplneny a tim padem nelze volat storeRequest():

<?php
	/** @deprecated */
	function storeRequest($expiration = '+ 10 minutes')
	{
		return $this->presenter->storeRequest($expiration);
	}

?>

Napada vas, co delam blbe, nebo na co se jeste podivat ?

vitmichal
Člen | 6
+
0
-

Tak chyba opravena. Zpusobeno volanim $this->getApplication()->storeRequest(); misto $this->getPresenter()->storeRequest();