我们正在使用Zend framework 1.11.11。我们的服务器有PHPUnit 3.7.9。我们知道我们的Zend Framework版本不支持PHPUnit 3.7.9。但到目前为止,我们已经能够使用PHPUnit来测试模型。
然而,当涉及到测试控制器时,PHPUnit失败了。将dispatch()
代码放入try/catch block
后,我们了解到无法从Zend_Registry
加载一个属性。它定义为application.ini
。在模型中使用相同的属性,我们没有问题。
我们可能遗漏了什么吗?或者是不可能将PHPUnit 3.7.9与我们的ZF版本一起使用?
这是phpunit.xml:
<phpunit bootstrap="./application/bootstrap.php" colors="true">
<testsuite name="Precision Tests">
<directory>./</directory>
</testsuite>
<filter>
<whitelist>
<directory suffix=".php">../application/</directory>
<directory suffix=".php">../library/</directory>
<exclude>
<directory suffix=".phtml">../application/</directory>
<directory>../library/Zend</directory>
<file>../application/Bootstrap.php</file>
<file>../application/controllers/ErrorController.php</file>
</exclude>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="./log/report" charset="UTF-8" yui="true" hightlight="true"
lowupperbound="50" highlowerbound="80">
<log type="testdox" target="./log/testdox.html">
</log>
</log>
</logging>
</phpunit>
测试中的bootstrap.php:
<?php
function load($name) {
$paths = array(
"../application/controllers",
"../library",
"../application/models"
);
foreach($paths as $dir) {
$name = str_replace("_", "/", $name);
if(file_exists($dir."/".$name.".php")) {
require_once($dir."/".$name.".php");
break;
}
}
}
error_reporting(E_ALL | E_STRICT);
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../application'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));
$_SERVER["APPLICATION_ENV"] = getenv('APPLICATION_ENV');
$_SERVER["APPLICATION_ENV"] = 'development';
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
realpath(APPLICATION_PATH . '/controllers'),
get_include_path(),
)));
require_once 'Zend/Application.php';
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
//setting up env variables:
$_SERVER["REMOTE_ADDR"] = '0.0.0.0';
$_SERVER['SERVER_NAME'] ='PHP.UNIT.TEST';
$_SERVER['REQUEST_URI'] = 'PHPUNITTEST';
$_SERVER['QUERY_STRING'] = 'PHPUNITTEST';
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('VP');
$autoloader->pushAutoloader("load");
spl_autoload_register();
require_once 'ControllerTestCase.php';
然后是ControllerTestCase.php
。我们的模型也扩展了相同的ControllerTestCase
:
<?php
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';
class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
/**
* @var Zend_Application
*/
protected $application;
public function setUp() {
$this->bootstrap = array($this, 'appBootstrap');
parent::setUp();
}
public function appBootstrap() {
$this->application = new Zend_Application(APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini');
$this->application->bootstrap();
}
}
这是一个不从application.ini加载属性的示例控制器:
<?php
class MyControllerTest extends ControllerTestCase
{
public function setUp()
{
$this->getFrontController()->setControllerDirectory(APPLICATION_PATH . '/controllers');
Zend_Controller_Action_HelperBroker::addHelper(new Zend_Layout_Controller_Action_Helper_Layout);
}
public function testSubscriptionStatus()
{
try{
$this->dispatch('/my/subscriptionstatus');
$this->assertController('my');
$this->assertAction('subscriptionstatus');
} catch (Exception $e) {
print_r($e->getTrace());
}
}
}
在这里我们如何设置我们的测试模型:
<?php
class Model_CustomerTest extends ControllerTestCase
{
public function testDoSearch(){
$x = Customer::doSearch('s');
$this->assertTrue(count($x) > 0);
}
}
最后这里冒犯的代码适用于模型,但不适用于控制器(运行PHPUnit时):
$registry = Zend_Registry::getInstance();
$options = $registry->webservices['logging'];
我们通过阅读网络上的几个不同资源来设置我们的PHPUnit测试环境。我们都不是PHPUnit专家。所以我们只是不知道发生了什么。
谢谢!
答案 0 :(得分:5)
文档对此不是很清楚,但我认为控制器测试用例类实际上不应该进行自举,因为PHPUnit需要能够在每次测试之前执行此操作。至少这是我的控制器基类(工作)设置的方式。因此,请尝试更改您的设置方法:
public function setUp() {
$this->bootstrap = new Zend_Application(APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini');
parent::setUp();
}
答案 1 :(得分:1)
ZEND1
我搜索了一个解决方案,但没有任何接近真正的解决方案,所以我发布了我的全班,有人看我是如何工作的。我希望这会有所帮助。
<?php
//We need to include these resources for bootstrapping of the Tests.
define('APPLICATION_ENV', "developer");
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '../../../application'));
$libraryPath = realpath(dirname(__FILE__) . '../../../library');
set_include_path($libraryPath. PATH_SEPARATOR . get_include_path());
require_once 'Zend/Application.php';
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';
class CommentControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
protected $_application;
protected $front;
protected function setUp()
{
$this->bootstrap = array($this, 'appBootstrap');
parent::setUp();
}
public function appBootstrap()
{
$this->_application = new Zend_Application(APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$this->_application->bootstrap();
/**
* Fix for ZF-8193
* http://framework.zend.com/issues/browse/ZF-8193
* Zend_Controller_Action->getInvokeArg('bootstrap') doesn't work
* under the unit testing environment.
*/
$this->front = Zend_Controller_Front::getInstance();
if($this->front->getParam('bootstrap') === null) {
$this->front->setParam('bootstrap', $this->_application->getBootstrap());
}
}
public function testGoHome()
{
$this->dispatch('/');
$request = $this->getRequest();
$request->setMethod('POST')
->setPost(array(
'username' => 'yourusername',
'password' => 'putpassword',
));
$this->dispatch('/');
$this->assertNotRedirect();
$this->assertQuery('form');
}
}
之后,将其保存为application / controllers文件夹中的CommentControllerTest.php。使用终端,导航到controllers文件夹并运行以下命令。
phpunit CommentControllerTest