Fatal error: Call to a member function getService()
- RDPanek
- Člen | 189
Ahoj, chci spustit životní cyklus presenteru:
$presenter = new HomepagePresenter;
$request = new PresenterRequest('Homepage', 'GET', array());
$response = $presenter->run($request);
ale třetí řádek mi vyhazuje chybku:
Fatal error: Call to a member function getService() on a non-object in
/Volumes/htdocs/projects/libs/Nette/Application/Presenter.php on line 1250
prosel jsem si forum, ale na reseni jsem nenarazil. Díky
- Filip Procházka
- Moderator | 4668
V tom případě jsi fórum procházel špatně.
Presenter závisí na předaném kontextu s určitou množinou služeb, které přímo využívá.
Nejsnadnější bude asi nechat si vyrobit $context
od
Configurator
u
$configurator = new Nette\Configurator;
$container = $configurator->getContainer();
$presenter = new Presenter;
$presenter->setContext($container);
$request = new PresenterRequest('Homepage', 'GET', array());
$response = $presenter->run($request);
Je potřeba dávat bacha na Configurator
a
Container
. Protože Configurator
je kapku ohackovaný
kvůli kompatibilitě s Environment
.
Za tuhle radu se stydím, ale nejjednodušší způsob jak
$container
v testech získat je
$context = Nette\Environment::getContext()
. Pokud to chceš ale
udělat pořádně, pak směle do toho.
Pokud někdo má nápad, jak ho získat lépe, pak sem s ním. Testovat presentery se mi totiž zatím moc nechce.
PHPUnit sám o sobě je hromádka statických tříd, takže to půjde dost blbě…
- kravčo
- Člen | 721
Možno skôr stálo za to pozrieť sa do súboru
.../Nette/Application/Presenter.php
na riadok 1250…
Okrem toho nie je jasné, akú máš verziu Nette, PHP ani nič iné. Tipol by som však, že inkriminovaný riadok vyzerá nejak takto:
final public function getService($name)
{
return $this->context->getService($name); // <-- riadok 1250
}
To čo v takom prípade potrebuješ je nastaviť prezenteru kontext, predtým ako ho spustíš:
$presenter->setContext(Nette\Environment::getContext());
Prípadne ak testovanie nejako súvisí so službami, možno budeš potrebovať vlastný mock objekt kontextu.
- Nox
- Člen | 378
A proč teda ne Configurator::getContainer?
Nebo případně si dej MyTestCase::getContext/ainer (má to context X container vůbec nějakou logiku nebo je jen na zmatení nepřítele?) a do nej si klidně Environment::getContext() dej – v tom není vůbec problém, protože způsob jakým kontext získáváš je pak vyměnitelný a sám Environment ho nezískává nijak svévolně, ale přes injecnutý Container – opět flexibilní
- kravčo
- Člen | 721
HosipLan napsal(a):
Nejsnadnější bude asi nechat si vyrobit
$context
odConfigurator
u
Najjednoduchšie je získať ho z Environment
.
$configurator = new Nette\Configurator; $container = $configurator->getContainer(); // ...
Za tuhle radu se stydím, ale nejjednodušší způsob jak
$container
v testech získat je$context = Nette\Environment::getContext()
. Pokud to chceš ale udělat pořádně, pak směle do toho.
V tom prípade by si sa mal hanbiť aj za tú predošlú. Pretože
Nette\Environment::getContext()
spraví presne to isté.
Treba si uvedomiť že sme v kóde testu a ak chceme mockovať, použijeme
priamo vlastný kontext a Configurator
ani Environment
nám vôbec netreba:
$presenter->setContext(new MockContext);
V opačnom prípade nie je dôvod nepoužiť Environment
.