简体   繁体   English

如何将其他参数传递给routeMatch对象?

[英]How can I pass extra parameters to the routeMatch object?

I'm trying to unit test a controller, but can't figure out how to pass some extra parameters to the routeMatch object. 我正在尝试对控制器进行单元测试,但无法弄清楚如何将一些额外的参数传递给routeMatch对象。

I followed the posts from tomoram at http://devblog.x2k.co.uk/unit-testing-a-zend-framework-2-controller/ and http://devblog.x2k.co.uk/getting-the-servicemanager-into-the-test-environment-and-dependency-injection/ , but when I try to dispatch a request to /album/edit/1, for instance, it throws the following exception: 我关注了tomoram的帖子,网址为http://devblog.x2k.co.uk/unit-testing-a-zend-framework-2-controller/http://devblog.x2k.co.uk/getting-the- servicemanager- to -test-environment-and-dependency-injection / ,但是例如,当我尝试将请求分派到/ album / edit / 1时,它将引发以下异常:

Zend\Mvc\Exception\DomainException: Url plugin requires that controller event compose a router; none found

Here is my PHPUnit Bootstrap: 这是我的PHPUnit Bootstrap:

class Bootstrap
{
    static $serviceManager;
    static $di;

    static public function go()
    {
        include 'init_autoloader.php';

        $config = include 'config/application.config.php';
        // append some testing configuration
        $config['module_listener_options']['config_static_paths'] = array(getcwd() . '/config/test.config.php');

        // append some module-specific testing configuration
        if (file_exists(__DIR__ . '/config/test.config.php')) {
            $moduleConfig = include __DIR__ . '/config/test.config.php';
            array_unshift($config['module_listener_options']['config_static_paths'], $moduleConfig);
        }

        $serviceManager = Application::init($config)->getServiceManager();

        self::$serviceManager = $serviceManager;

        // Setup Di
        $di = new Di();

        $di->instanceManager()->addTypePreference('Zend\ServiceManager\ServiceLocatorInterface', 'Zend\ServiceManager\ServiceManager');
        $di->instanceManager()->addTypePreference('Zend\EventManager\EventManagerInterface', 'Zend\EventManager\EventManager');
        $di->instanceManager()->addTypePreference('Zend\EventManager\SharedEventManagerInterface', 'Zend\EventManager\SharedEventManager');

        self::$di = $di;
    }

    static public function getServiceManager()
    {
        return self::$serviceManager;
    }

    static public function getDi()
    {
        return self::$di;
    }

}

Bootstrap::go();

Basically, we are creating a Zend\\Mvc\\Application environment. 基本上,我们正在创建一个Zend\\Mvc\\Application环境。

My PHPUnit_Framework_TestCase is enclosed in a custom class, which goes like this: 我的PHPUnit_Framework_TestCase包含在一个自定义类中,如下所示:

abstract class ControllerTestCase extends TestCase
{
    /**
     * The ActionController we are testing
     *
     * @var Zend\Mvc\Controller\AbstractActionController
     */
    protected $controller;

    /**
     * A request object
     *
     * @var Zend\Http\Request
     */
    protected $request;

    /**
     * A response object
     *
     * @var Zend\Http\Response
     */
    protected $response;

    /**
     * The matched route for the controller
     *
     * @var Zend\Mvc\Router\RouteMatch
     */
    protected $routeMatch;

    /**
     * An MVC event to be assigned to the controller
     *
     * @var Zend\Mvc\MvcEvent
     */
    protected $event;

    /**
     * The Controller fully qualified domain name, so each ControllerTestCase can create an instance
     * of the tested controller
     *
     * @var string
     */
    protected $controllerFQDN;

    /**
     * The route to the controller, as defined in the configuration files
     *
     * @var string
     */
    protected $controllerRoute;

    public function setup()
    {
        parent::setup();

        $di = \Bootstrap::getDi();

        // Create a Controller and set some properties
        $this->controller = $di->newInstance($this->controllerFQDN);

        $this->request    = new Request();
        $this->routeMatch = new RouteMatch(array('controller' => $this->controllerRoute));
        $this->event      = new MvcEvent();

        $this->event->setRouteMatch($this->routeMatch);

        $this->controller->setEvent($this->event);
        $this->controller->setServiceLocator(\Bootstrap::getServiceManager());
    }

    public function tearDown()
    {
        parent::tearDown();
        unset($this->controller);
        unset($this->request);
        unset($this->routeMatch);
        unset($this->event);
    }
}

And we create a Controller instance and a Request with a RouteMatch. 然后,我们创建一个Controller实例和一个带有RouteMatch的请求。

The code for the test: 测试代码:

public function testEditActionWithGetRequest()
{
    // Dispatch the edit action
    $this->routeMatch->setParam('action', 'edit');
    $this->routeMatch->setParam('id', $album->id);
    $result = $this->controller->dispatch($this->request, $this->response);

    // rest of the code isn't executed
}

I'm not sure what I'm missing here. 我不确定我在这里缺少什么。 Can it be any configuration for the testing bootstrap? 它可以是测试引导程序的任何配置吗? Or should I pass the parameters in some other way? 还是应该以其他方式传递参数? Or am I forgetting to instantiate something? 还是我忘记实例化某些东西?

What I did to solve this problem was move the Application::init() and the configuration from the Bootstrap to the setUp() method. 我要解决的问题是将Application::init()和配置从Bootstrap移到setUp()方法。 It takes a while to load, but it works. 加载需要一段时间,但是可以正常工作。

My Bootstrap has only the code needed to configure the autoloader, while the setUp() method has something similar to the old Bootstrap::go() code. 我的Bootstrap仅具有配置自动加载器所需的代码,而setUp()方法与旧的Bootstrap::go()代码类似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM