Testování formuláře – simulace odeslání
- Casper
- Člen | 253
Zdravím, snažím se nasimulovat odeslání formuláře, ale po
„odeslání“ z formuláře nic nedostanu, dokonce ani metoda
onSuccess[]
se vůbec nezavolá. Dělám něco
špatně?
Testovací presenter obsahuje pouze metodu renderDefault s odesláním
TextResponse
.
public function testSubmitted(){
$request = new \Nette\Application\Request("Test", 'POST', array(
"action" => "default",
"do" => "contactForm-submit",
), array(
"name" => "John",
"email" => "example@gmail.com",
"subject" => "Testing",
"content" => "Well...",
));
$presenterFactory = $this->container->getByType('Nette\Application\IPresenterFactory');
$formFactory = $this->container->getByType('Forms\IContactFormFactory');
$presenter = $presenterFactory->createPresenter('Test');
$form = $formFactory->create();
$presenter->addComponent($form, "contactForm");
$presenter->run($request);
var_dump($form->getErrors()); // prázdné
var_dump($form->getValues()); // všechny hodnoty jsou NULL
}
Jedu na Nette 2.1dev
- David Matějka
- Moderator | 6445
myslim, ze pritomnost tovarnicky nehraje roli. ten formular je pripojenej pres addComponent, coz by melo byt dostacujici.. chyba bude tedy asi jinde
ted me napada, nevim presne jak to je, ale nemenilo se nejak, ze
do
parametr se u formularu posila v post?
Editoval matej21 (16. 10. 2013 20:26)
- Casper
- Člen | 253
Tak jsem si to odkrokoval a v metodě fireEvents
při volání
isSubmitted()
je submittedBy
FALSE,
nikoli NULL a proto se nenačtou http data.
final public function isSubmitted(){
if ($this->submittedBy === NULL) {
$this->getHttpData();
}
return $this->submittedBy;
}
To bude asi ta příčina, protože díky tomu to z metody
fireEvents
vyskočí hned ven. Nicméně manuální nastavení
setSubmittedBy
na odesílací button nebo na NULL mi nepomohlo.
Aneb při nastavení odesílací tlačítko, dostanu chyby ze všech required
inputů, protože se nepřijmou žádná httpData. A na NULL
to
nastavit nelze díky setteru:
public function setSubmittedBy(ISubmitterControl $by = NULL){
$this->submittedBy = $by === NULL ? FALSE : $by;
return $this;
}
Co bych měl tedy udělat, aby se toto zjišťovalo korektně?
P.S. parametr do
se skutečně odesílá
v POSTu, nicméně to problém neřeší :)
- Casper
- Člen | 253
Tak jsem na to kápnul, submittedBy bylo FALSE
protože
již při volání addComponent se volá getHttpData a ty v tu
chvíli nejsou k dispozici, takže se nastaví
na FALSE. Řešením je tedy nějaký vlastní callback pro připojení
komponent v presenteru.
$presenter = $presenterFactory->createPresenter('Test');
$presenter->onStartup[] = function($thePresenter) use ($form) {
$thePresenter->addComponent($form, "contactForm");
};
$response = $presenter->run($request);
- llook
- Člen | 407
vvoody napsal(a):
Alebo neznásilňovať nette a napísať továrničku do presenteru miesto volanie addComponent pred run. ;)
Tohle není znásilňování Nette, tohle je testování samotné komponenty bez nějakého konkrétního presenteru (protože komponenta je na konkrétním presenteru nezávislá). Řešení přes onStartup mi přijde velmi dobré.
- vvoody
- Člen | 910
Nie som do testovania nejaký odborník ale myslím že jeho pointa je nasimulovať najreálnejšie podmienky. Rozdiel medzi onStartup riešením a napísaním si vlastného presenteru s továrničkou je ten, že componenta je vytvorená v rozdielnych častiach životného cyklu presenteru čo by mohlo viesť k neodhaleniu určitých problémov.
- llook
- Člen | 407
To je pravda. Pak to lze teda dělat ještě takto:
class TestPresenter extends \Nette\Application\UI\Presenter
{
public $componentFactories = array();
protected function createComponent($name)
{
if (isset($this->componentFactories[$name]))
{
return $this->componentFactories[$name]($this, $name);
}
return parent::createComponent($name);
}
}
...
$presenter = $presenterFactory->createPresenter('Test');
$presenter->componentFactories['contactForm'] = function() use ($form) {
return $form;
};