We're using ZF2 for an web-application and want to test it with phpunit (v4.8.9). Within this application we've got a scheme-route, to be able to switch between http/https-context (Doesnt matter why...). The route looks like this:
'http' => array(
'type' => 'Scheme',
'options' => array(
'scheme' => 'http',
'defaults' => array(
'http' => true
)
),
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/search[/:keyword[/:page]]',
'constraints' => array(
'page' => '[1-9]+[0-9]*'
),
'defaults' => array(
'controller' => SearchController::class,
'action' => 'search',
),
),
),
),
),
'https' => array(
'type' => 'Scheme',
'options' => array(
'scheme' => 'https',
'defaults' => array(
'https' => true
)
),
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/search[/:keyword[/:page]]',
'constraints' => array(
'page' => '[1-9]+[0-9]*'
),
'defaults' => array(
'controller' => SearchController::class,
'action' => 'search',
),
),
),
),
),
The class of the test looks like this:
class SearchControllerTest extends SynHttpControllerTestCase
{
public function setUp()
{
$this->setApplicationConfig($this->getCurrentBootstrap()->getApplicationConfig());
parent::setUp();
$this->getApplicationServiceLocator()->setAllowOverride(true);
}
public function testSearchActionCanBeAccessed()
{
$this->dispatch('/search');
$this->assertResponseStatusCode(200);
$this->assertControllerName(SearchController::class);
$this->assertControllerClass('SearchController');
$this->assertActionName('search');
$this->assertMatchedRouteName('search');
}
}
FYI: The "SynHttpControllerTestCase" is an extension from the original AbstractHttpControllerTestCase which comes with Zend-Test. It's modified to get the right bootstrap-file in our tests.
If we're running the tests, this error appears:
Fatal error: Call to a member function getParam() on null in C:\\xampp\\htdocs\\git\\xxx\\vendor\\zendframework\\zend-test\\src\\PHPUnit\\Controller\\AbstractControllerTestCase.php on line 563
We looked into the AbstractControllerTestCase and this line is throwing the error:
$routeMatch = $this->getApplication()->getMvcEvent()->getRouteMatch();
Because the $routeMatch-Object is empty. We've some other controllers and tests within our application, they're all fine and not affected from this problem, cause the routes to these controllers arent scheme-routes.
Do you have any ideas how to solve this? In advance: we're not able to use static https-routes in this case.
There is a lot of official documentation on how to write a proper controller test. In your setUp
method you need to attach a Router
instance to a RouteMatch
instance which you attach to a MvcEvent
in the controller.
protected function setUp()
{
$serviceManager = Bootstrap::getServiceManager();
$this->controller = new IndexController();
$this->request = new Request();
$this->routeMatch = new RouteMatch(array('controller' => 'index'));
$this->event = new MvcEvent();
$config = $serviceManager->get('Config');
$routerConfig = isset($config['router']) ? $config['router'] : array();
$router = HttpRouter::factory($routerConfig);
$this->event->setRouter($router);
$this->event->setRouteMatch($this->routeMatch);
$this->controller->setEvent($this->event);
$this->controller->setServiceLocator($serviceManager);
}
Then you can call dispatch
.
Can you not set your route match object like this:
$routeParams = array('controller' => 'search', 'action' => 'search');
$routeMatch = new RouteMatch($routeParams);
$routerConfig = isset($config['router']) ? $config['router'] : array();
$router = HttpRouter::factory($routerConfig);
$event = new MvcEvent();
$event->setRouter($router);
$event->setRouteMatch($routeMatch);
$this->getApplication()->setMvcEvent($event);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.