我在我的Phalcon项目中集成了PHPUnit。我让它在MAMP中正确运行,但是当我在服务器上运行phpunit
时,我不断收到一些错误。
这是UnitTestCase:
<?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 \Phalcon\Mvc\Model\Manager as ModelsManager;
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();
DI::reset();
$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);
...and some more...
$di->set(
'modelsManager',
function()
{
return new \Phalcon\Mvc\Model\Manager();
}
);
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().');
}
}
}
所以,当我在本地机器上运行时,这很好用。当我在服务器上运行它时,它会抛出:
Phalcon\Di\Exception: Service 'modelsManager' wasn't found in the dependency injection container
我做错了什么?
答案 0 :(得分:0)
不是在测试中单独设置所有内容,而是应该选择一种引导程序解决方案。
我的引导程序文件包含在简短的 TestHelper.php 中:
$('.select').change(function() {
var value = $(this).val();
var src = $(this).find('option:selected').data('src');
$("#gallery .imgsx").prop('src', src).css('opacity', '0.5');
$(".loading").css('opacity', '1');
});
$("#gallery .imgsx").on("load", function() {
$("#gallery .imgsx").css('opacity', '1');
$(".loading").css('opacity', '0');
});
在 phpunit.xml 中正确配置支持:
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
defined('APPLICATION_ENV') || define('APPLICATION_ENV', getenv('APPLICATION_ENV') ?: 'developer');
defined('APPLICATION_DIR') || define('APPLICATION_DIR', 'app');
defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . APPLICATION_DIR) . DIRECTORY_SEPARATOR);
use Phalcon\DI;
$config = include_once(APPLICATION_PATH . 'config' . DIRECTORY_SEPARATOR . 'config.php');
$di = new Phalcon\DI\FactoryDefault();
$di->set('config', $config);
$application = new \Phalcon\Mvc\Application($di);
include_once(APPLICATION_PATH . 'autoload.php');
DI::setDefault($di);
$_SESSION = [];
Bootstrap文件应该包含运行完整应用程序所需的所有内容。请记住,您正在测试内容,因此不应替换任何逻辑,只需定义应在标准<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./TestHelper.php"
backupGlobals="false"
backupStaticAttributes="true"
verbose="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="true">
<testsuites>
<testsuite name="Application - Testsuite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<directory>../vendor</directory>
</blacklist>
</filter>
<logging>
<log type="coverage-html" target="../public/build/coverage" title="PHP Code Coverage"
charset="UTF-8" yui="true" highlight="true"
lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="../public/build/logs/clover.xml"/>
<log type="junit" target="../public/build/logs/junit.xml" logIncompleteSkipped="false"/>
</logging>
</phpunit>
文件的初始化时定义的内容,并包括必须包含的内容,但远离< / strong>从运行与index.php
相关的任何内容。您只是在为应用程序预热,将所有依赖项构建到其中。我的最终$application->handle()
与我的bootsrap有一个try / catch块,自定义 error2exception 处理程序和index.php
。
所有内容都包含在这样的结构中:
echo $application->handle()->getContent();
一旦你的应用程序 - 我猜 - 除了测试之外正常工作,你应该尝试以正确的方式继承原始结构中的所有内容,而不是为每个测试声明一切。
* app/
| |- config/
| |- ...
| '- autoload.php
* public/
| |- css/
| |- ...
| '- index php
* vendor/
* tests/
* app/
|- // whole app/ structure
|- TestHelper.php
'- phpunit.xml
的示例性测试/tests/app/models/services/DeviationTest.php
:
/app/models/services/deviation.php
由于方法的制定如果出现任何问题他们会抛出异常,我甚至不需要做任何断言 - 现在,这是一个验收测试。
答案 1 :(得分:0)
我只是遇到了同样的问题,花了一些时间才弄清楚。我显然确实将所有服务都包含在单独的“引导”文件中,以防止丢失/复制DI服务。
通过添加以下内容为我解决了该问题:
/**
* Function to setup the test case
*/
public function setUp()
{
// Get reference to the global DI var (with all my registered services):
global $di;
// Setup parent:
parent::setUp();
// --------------------------------------------------
// THIS IS WHAT SOLVED IT FOR ME, since Phalcon
// Set default DI
// uses the \Phalcon\Di::getDefault() for handling queries from a model:
\Phalcon\Di::setDefault($di);
// --------------------------------------------------
// Set the DI:
$this->setDI($di);
}