Jak simulovat odeslání formuláře

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

Potřeboval bych otestovat chování formuláře po odeslání.

Představoval bych si to asi tak, že mocknu kontext a někam podstrčím vlastní HttpRequest, ale prakticky se mi to nedaří realizovat. Myslel jsem, že by mohlo fungovat něco podobného:

	public function testSomething()
	{
		$postVars = array(
			'A' => 'foo',
			'B' => 'bar'
		);
		$request = new \Nette\Http\Request(new \Nette\Http\UrlScript('/'), null, $postVars);
		$context = $this->getMock('\SystemContainer');
		$context->expects($this->any())
				->method('getHttpRequest')
				->will($this->returnValue($request));
		\Nette\Environment::setContext($context);
		$form = new \Nette\Forms\Form;
		$form->addText('A');
		$form->addText('B');
		$this->assertTrue($form->isSubmitted());
	}

Jenže to skončí chybou „Fatal error: Call to a member function getMethod() on a non-object“ v „libs\Nette\Forms\Form.php on line 457“. Zkoušel jsem překrýt i __get, __call a getService, se stejným výsledkem. Tak už nevím, lze vůbec nějak podstrčit formuláři jiný request?

llook
Člen | 407
+
0
-

Tak jsem na to přišel, stačilo pár hodin se prospat… Vůbec nemusím mockovat celý kontext, stačí překrýt Form::getHttpRequest:

	public function testSomething()
	{
		$postVars = array(
			'A' => 'foo',
			'B' => 'bar'
		);
		$request = new \Nette\Http\Request(new \Nette\Http\UrlScript('/'), null, $postVars, null, null, null, 'POST');

		//$form = new \Nette\Forms\Form;
		$form = $this->getMock('Nette\Forms\Form', array('getHttpRequest'));
		$form->expects($this->any())
				->method('getHttpRequest')
				->will($this->returnValue($request));

		$form->addText('A');
		$form->addText('B');
		$values = $form->getValues();
		$this->assertTrue((bool) $form->isSubmitted());
		$this->assertEquals('foo', $values['A']);
	}

Tohle už projde podle očekávání.

Filip Procházka
Moderator | 4668
+
0
-

A kdybys chtěl robustnější řešení, tak stačí kouknout sem :)

RDPanek
Člen | 189
+
0
-

Jedna otázka – je těžké si nainstancovat tvůj formulář a použít je v testech? k mockování bych se přiklonil v případě, kdyby bylo komplikované již existující formulář použít nebo pokud ještě neexistuje.

llook
Člen | 407
+
0
-

RDPanek napsal(a):

Jedna otázka – je těžké si nainstancovat tvůj formulář a použít je v testech? k mockování bych se přiklonil v případě, kdyby bylo komplikované již existující formulář použít nebo pokud ještě neexistuje.

B je správně, píšu si takový builder editačních formulářů. Dám tomu formulář a entitu a ono mi to do formuláře přidá jednak inputy (podle reflexe té entity) a jednak onSuccess, který tu entitu nasetuje. Je to hloupý kód, ale během vývoje se občas hodí.

Ale i u vlastního ručně sestaveného formuláře bych asi nakonec skončil u stejného řešení, pouze by se změnil první parametr metody getMock. Řešení z Kdyby mi přijde už zbytečně komplikované, ale možná se tím inspiruju při testování jiných controlů.