Phalcon unittests未通过

时间:2016-03-07 13:44:31

标签: php phpunit phalcon

我正在尝试设置单元测试,但我根本没有运气。我在TestHelper.php文件夹中创建了tests。该文件如下所示:

<?php
use Phalcon\Di;
use Phalcon\Di\FactoryDefault;

ini_set('display_errors',1);
error_reporting(E_ALL);

define('ROOT_PATH', __DIR__);
define('PATH_LIBRARY', __DIR__ . '/../app/library/');
define('PATH_SERVICES', __DIR__ . '/../app/services/');
define('PATH_RESOURCES', __DIR__ . '/../app/resources/');

define('BASE_DIR', dirname(__DIR__));
define('APP_DIR', BASE_DIR . '/app');

set_include_path(
    ROOT_PATH . PATH_SEPARATOR . get_include_path()
);

// Required for phalcon/incubator
include __DIR__ . "/../vendor/autoload.php";

// Use the application autoloader to autoload the classes
// Autoload the dependencies found in composer
$loader = new \Phalcon\Loader();

$loader->registerDirs(
    array(
        ROOT_PATH
    )
);

$config = include APP_DIR . '/config/config.php';

$loader->registerNamespaces(array(
    'MyApp\Models' => $config->application->modelsDir,
    'MyApp\Controllers' => $config->application->controllersDir,
    'MyApp\Forms' => $config->application->formsDir,
    'MyApp\Classes' => $config->application->classesDir,
    'MyApp' => $config->application->libraryDir
));

$loader->register();

我还创建了UnitTestCase.php

<?php
use Phalcon\Di;
use Phalcon\DI\FactoryDefault;
use Phalcon\Test\UnitTestCase as PhalconTestCase;
use Phalcon\Mvc\View;
use Phalcon\Crypt;
use Phalcon\Mvc\Dispatcher;
use \Phalcon\Mvc\Dispatcher as PhDispatcher;
use Phalcon\Mvc\Url as UrlResolver;
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
use Phalcon\Mvc\View\Engine\Volt as VoltEngine;
use Phalcon\Mvc\Model\Metadata\Files as MetaDataAdapter;
use Phalcon\Session\Adapter\Files as SessionAdapter;
use Phalcon\Flash\Direct as Flash;
use Phalcon\Logger;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Logger\Adapter\File as LoggerFile;
use MyApp\Auth\Auth;
use MyApp\AuthPublic\AuthPublic;
use MyApp\Acl\Acl;
use MyApp\CacheData\CacheData;
use MyApp\Mail\Mail;
use MyApp\PHPExcel\PHPExcel;
abstract class UnitTestCase extends PhalconTestCase
{
    /**
     * @var \Voice\Cache
     */
    protected $_cache;
    /**
     * @var \Phalcon\Config
     */
    protected $_config;
    /**
     * @var bool
     */
    private $_loaded = false;
    public function setUp(Phalcon\DiInterface $di = NULL, Phalcon\Config $config = NULL)
    {
        // Load any additional services that might be required during testing
        $di = new FactoryDefault();
        $config = include APP_DIR . '/config/config.php';
        /**
         * The URL component is used to generate all kind of urls in the application
         */
        $di->set('url', function () use ($config) {
            $url = new UrlResolver();
            $url->setBaseUri($config->application->baseUri);
            return $url;
        }, true);
        /**
         * Setting up the view component
         */
        $di->set('view', function () use ($config) {
            $view = new View();
            $view->setViewsDir($config->application->viewsDir);
            $view->registerEngines(array(
                '.volt' => function ($view, $di) use ($config) {
                    $volt = new VoltEngine($view, $di);
                    $volt->setOptions(array(
                        'compiledPath' => $config->application->cacheDir . 'volt/',
                        'compiledSeparator' => '_'
                    ));
                    return $volt;
                }
            ));
            return $view;
        }, true);
        /**
         * Database connection is created based in the parameters defined in the configuration file
         */
        $di->set('db', function () use ($config) {
            $eventsManager = new EventsManager();

            // Debug sql logging //
            $is_debug_sql_logging = true;
            if ( $is_debug_sql_logging )
            {
                $logger = new LoggerFile( $config->application->logsDir ."debug_sql.log" );
                $logger->log( "\n------\n" );

                // Listen all the database events //
                $eventsManager->attach( 'db', function( $event, $connection ) use ($logger) {
                    if ( $event->getType() == 'beforeQuery' ) {
                        $log_message = $connection->getRealSQLStatement()."\n".print_r( $connection->getSQLVariables(), true );
                        $logger->log( $log_message, Logger::DEBUG );
                    }
                    if ($event->getType() == 'afterQuery') {
                        //...//
                    }
                });
            }
            // Database connection //    
            $dbAdapter = new DbAdapter(array(
                'host' => 'localhost',
                'username' => 'root',
                'password' => 'root',
                'dbname' => 'database'
            ));
            //Assign the eventsManager to the db adapter instance
            $dbAdapter->setEventsManager( $eventsManager );

            return $dbAdapter;
        });
        /**
         * If the configuration specify the use of metadata adapter use it or use memory otherwise
         */
        $di->set('modelsMetadata', function () use ($config) {
            return new MetaDataAdapter(array(
                'metaDataDir' => $config->application->cacheDir . 'metaData/'
            ));
        });

        $di->set('modelsManager', function() {
            return new \Phalcon\Mvc\Model\Manager();
        });
        /**
         * Start the session the first time some component request the session service
         */
        $di->set('session', function () {
            $session = new SessionAdapter();
            $session->start();
            return $session;
        });
        /**
         * Cache of models
         */
        $di->set('cache', function () {
            $cacheData = new CacheData();

            return $cacheData;
        });
        /**
         * Crypt service
         */
        $di->set('crypt', function () use ($config) {
            $crypt = new Crypt();
            $crypt->setKey($config->application->cryptSalt);
            return $crypt;
        });
        /**
        * Set a 404 redirect AND use a default namespace
        */
        $di->set('dispatcher', function() use ($di) {
                $evManager = $di->getShared('eventsManager');
                $evManager->attach(
                    "dispatch:beforeException",
                    function($event, $dispatcher, $exception)
                    {
                        switch ($exception->getCode()) {
                            case PhDispatcher::EXCEPTION_HANDLER_NOT_FOUND:
                            case PhDispatcher::EXCEPTION_ACTION_NOT_FOUND:
                                $dispatcher->forward(
                                    array(
                                        'controller' => 'error',
                                        'action'     => 'show404',
                                    )
                                );
                                return false;
                        }
                    }
                );
                $dispatcher = new PhDispatcher();
                $dispatcher->setEventsManager($evManager);

                /* Dispatcher use a default namespace */
                $dispatcher->setDefaultNamespace('MyApp\Controllers');

                return $dispatcher;
            },
            true
        );
        /**
         * Loading routes from the routes.php file
         */
        $di->set('router', function () {
            return require __DIR__ . '/routes.php';
        });
        /**
         * Flash service with custom CSS classes
         */
        $di->set('flash', function () {
            return new Flash(array(
                'error' => 'notification notification--error',
                'success' => 'notification notification--success',
                'notice' => 'notification notification--neutral',
                'general' => 'notification notification--general',
                'warning' => 'notification notification--warning'
            ));
        });
        /**
         * Authentication component
         */
        $di->set('auth', function () {
            return new Auth();
        });
        /**
         * Self test authentication component
         */
        $di->set('authPublic', function () {
            return new AuthPublic();
        });
        /**
         * Mail service uses AmazonSES
         */
        $di->set('mail', function () {
            return new Mail();
        });
        /**
         * Access Control List
         */
        $di->set('acl', function () {
            return new Acl();
        });
        /**
         * PHPExcel
         */
        $di->set('phpexcel', function () {
            return new PHPExcel();
        });
        parent::setUp($di, $config);
        $this->_loaded = true;
    }
    /**
     * Check if the test case is setup properly
     *
     * @throws \PHPUnit_Framework_IncompleteTestError;
     */
    public function __destruct()
    {
        if (!$this->_loaded) {
            throw new \PHPUnit_Framework_IncompleteTestError('Please run parent::setUp().');
        }
    }
}

还有phpunit.xml

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="TestHelper.php"
         backupGlobals="false"
         backupStaticAttributes="false"
         verbose="true"
         colors="false"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="true">
    <testsuite name="Phalcon - Testsuite">
        <directory>./</directory>
    </testsuite>
</phpunit>

所有这一切,应该让我能够运行一些单元测试。但是,当我转到终端中的tests文件夹并运行../vendor/bin/phpunit时,它会抛出错误。错误是Phalcon\Di\Exception: Service 'modelsManager' wasn't found in the dependency injection container。我一直在努力奋斗几个小时,我希望有人能够帮助我。我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

DI::setDefault($di);

中的parent::setUp($di, $config);之前添加UnitTestCase.php

通过这种方式,您可以全局访问DI组件,而不仅仅是在本地范围内。

UnitTestCase.php中的setUp()函数如下所示:

public function setUp()
{
    parent::setUp();
    $di = new FactoryDefault();
    // load all services.
    include APP_PATH . "/config/services.php";
    DI::setDefault($di);
    $this->setDi($di);
    $this->_loaded = true;
}

这样我可以通过$ this-&gt; di访问DI(例如:$ this-&gt; di-&gt; get(&#39; config&#39;))所有其他需要DI的相关库都可以获得它在全球范围内。