Mockování \Nette\Http\Session

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

Zdravím,
pokuším se napsat test presenteru, ale umírá to s hláškou AboutPresenterTest::testRenderDefault()
Nette\InvalidStateException: Cannot set cookie after HTTP headers have been sent (output started at /usr/share/php5/PEAR/PHPUnit/Util/Printer.php:173).

Dohledal jsem, že je problém v session, které se snaží vypustit cookies. Zkoušel jsem použít @runInSeparateProcess, ale pak PHPUnit umře na Exception: Serialization of ‚Closure‘ is not allowed in /usr/share/php5/PEAR/PHPUnit/Util/GlobalState.php:344.

Takže asi zbývá mockování session v containeru, ale už jsem nepřišel jak na to. TestCase vypadá takto:

<?php
/**
 * HomepagePresenter test
 */
class HomepagePresenterTest extends \PHPUnit_Framework_TestCase {

	/**
	 * @runInSeparateProcess
	 * @backupGlobals disabled
	 */
	public function testRenderDefault() {
		$presenter = new HomepagePresenter(Nette\Environment::getContext());

		$presenter->injectTranslator(new \NetteTranslator\Gettext($presenter->getContext()));
		$request = new Nette\Application\Request('Homepage', 'GET', array());

		$response = $presenter->run($request);
		$this->assertInstanceOf(
				'Nette\Application\Responses\TextResponse', $response
		);
	}
}
?>

V BasePresenter mam metodu startup(), která pracuje se session (to ale asi není důležité, se session pracuji na více místech v presnterech, tak to potřebuji vyřešit nějak definitivně :-).

<?php
	protected function startup() {
		parent::startup();
		/** presmerovani dle jazyka **/
		$sectionName = 'redirectByLang';

		if($this->session->hasSection($sectionName))
			return;

		if(!$this->isLinkCurrent(':Homepage:') || $this->getLang() === 'cs') {
			$this->session->getSection($sectionName)->redirected = true;
		}
		else {
			foreach(explode(',',$_SERVER["HTTP_ACCEPT_LANGUAGE"]) as $lg) {
				$lg = explode(';', $lg);
				if(in_array($lg[0],array('cs','cs-CZ'))) {
					$this->session->getSection($sectionName)->redirected = true;
					$this->redirect(':Homepage:', array('lang' => 'cs'));
				}
			}
		}
	}
?>
Michal Vyšinský
Člen | 608
+
0
-

Ahoj,
taky jsem se s tímto problémem potýkal. Pomohlo mi toto (phpunit.xml):

<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="bootstrap.php">
</phpunit>

Edit: Nevím, jaký to má dopad třeba na výkon, ale po dlouhém pátrání, jak problém vyřešit jsem byl rád, že mi to funguje.

Editoval CherryBoss (11. 6. 2013 17:39)

esorimer
Člen | 114
+
0
-

CherryBoss napsal(a):

Ahoj,
taky jsem se s tímto problémem potýkal. Pomohlo mi toto (phpunit .xml):

<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="bootstrap.php">
</phpunit>

Edit: Nevím, jaký to má dopad třeba na výkon, ale po dlouhém pátrání, jak problém vyřešit jsem byl rád, že mi to funguje.

Ahoj, mě to bohužel nefunguje :( Jakmile je použité @runInSeparateProcess, tak to vždycky umře na neseriazovatelnost a bez toho zase kvůli session.

Taky mě napadlo, když budu potřebovat vlastní implementaci Session (třeba takovou, co svá data šifruje apod.), jak jí do Nette dostanu?

esorimer
Člen | 114
+
0
-

Má někdo nějaký nápad? Dá se třída pro session nastavit v konfiguráku?

David Ďurika
Člen | 328
+
0
-

esorimer napsal(a):

Má někdo nějaký nápad? Dá se třída pro session nastavit v konfiguráku?

da

services:
	session: Kdyby\Tests\Http\FakeSession

https://gist.github.com/…pLan/5299296

Editoval achtan (13. 6. 2013 11:01)

esorimer
Člen | 114
+
0
-

Super, díky, funguje! Konečně vidím ty zelené fajfky :)

PS: Tohle by stálo za to dát do dokumentace testů…