Jak simulovat odeslání formuláře
- llook
- Člen | 407
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
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í.
- llook
- Člen | 407
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ů.