我正在尝试设置单元测试,但我根本没有运气。我在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
。我一直在努力奋斗几个小时,我希望有人能够帮助我。我在这里做错了什么?
答案 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的相关库都可以获得它在全球范围内。