dtng5978 2017-09-17 03:14
浏览 100
已采纳

单元测试CakePHP 3插件需要一个config / routes.php文件夹来测试Router :: url()

I am writing some tests for a CakePHP 3 plugin, and some of my actions use Router::url calls. When I run phpunit I get the following error: include([project dir]\\configoutes.php): failed to open stream: No such file or directory.

What I'd like to know is if this file is really required just for unit testing to work. If I create the file on that folder the testing works right. I have tried adding

DispatcherFactory::add('Asset'); DispatcherFactory::add('Routing'); DispatcherFactory::add('ControllerFactory');

to my tests/bootstrap.php file, however it did no change at all.

Since this is a standalone plugin I'd find it a little odd to have a config folder with a routes.php file in it for the sole purpose of testing. Is there any workaround to this?

  • 写回答

1条回答 默认 最新

  • dppb79372 2017-09-17 15:25
    关注

    The router requires a routes.php file to be present on application level, so what you should do is configure a test application environment where you can place such files.

    In your tests/bootstrap.php file, define the required constants and configuration that your test environment needs. If it where just for the router, it would probably be enough if you'd define the CONFIG constant accordingly, which is being used in \Cake\Routing\Router::_loadRoutes(), like

    define('CONFIG', dirname(__DIR__) . DS . 'tests' . DS . 'TestApp' . DS . 'config' . DS);
    

    This would set the config dir to tests/TestApp/config/, where you could place the routes.php file.

    Generally I'd recommend to setup all constants, and at least basic application configuration, here's an example from one of my plugins:

    use Cake\Core\Configure;
    use Cake\Core\Plugin;
    
    if (!defined('DS')) {
        define('DS', DIRECTORY_SEPARATOR);
    }
    define('ROOT', dirname(__DIR__));
    define('APP_DIR', 'src');
    define('APP_ROOT', ROOT . DS . 'tests' . DS . 'TestApp' . DS);
    define('APP', APP_ROOT . APP_DIR . DS);
    define('CONFIG', APP_ROOT . DS . 'config' . DS);
    define('WWW_ROOT', APP . DS . 'webroot' . DS);
    define('TESTS', ROOT . DS . 'tests' . DS);
    define('TMP', APP_ROOT . DS . 'tmp' . DS);
    define('LOGS', APP_ROOT . DS . 'logs' . DS);
    define('CACHE', TMP . 'cache' . DS);
    define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'vendor' . DS . 'cakephp' . DS . 'cakephp');
    define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
    define('CAKE', CORE_PATH . 'src' . DS);
    
    require_once ROOT . DS . 'vendor' . DS . 'autoload.php';
    require_once CORE_PATH . 'config' . DS . 'bootstrap.php';
    
    $config = [
        'debug' => true,
    
        'App' => [
            'namespace' => 'App',
            'encoding' => 'UTF-8',
            'defaultLocale' => 'en_US',
            'base' => false,
            'baseUrl' => false,
            'dir' => 'src',
            'webroot' => 'webroot',
            'wwwRoot' => WWW_ROOT,
            'fullBaseUrl' => 'http://localhost',
            'imageBaseUrl' => 'img/',
            'cssBaseUrl' => 'css/',
            'jsBaseUrl' => 'js/',
            'paths' => [
                'plugins' => [APP_ROOT . 'plugins' . DS],
                'templates' => [APP . 'Template' . DS],
                'locales' => [APP . 'Locale' . DS],
            ],
        ]
    ];
    Configure::write($config);
    
    date_default_timezone_set('UTC');
    mb_internal_encoding(Configure::read('App.encoding'));
    ini_set('intl.default_locale', Configure::read('App.defaultLocale'));
    
    Plugin::load('MyPlugin', ['path' => ROOT]);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?