4

我们正在使用 Zend 框架 1.11.11。我们的服务器有 PHPUnit 3.7.9。我们知道我们的 Zend Framework 版本不支持 PHPUnit 3.7.9。但到目前为止,我们已经能够使用 PHPUnit 来测试模型。

但是,在测试控制器时,PHPUnit 失败了。放入dispatch()代码后try/catch block,我们了解到它无法从Zend_Registry. 它被定义application.ini。模型中使用了相同的属性,我们在那里没有问题。

我们有可能遗漏了什么吗?还是不能在我们的 ZF 版本中使用 PHPUnit 3.7.9?

这是 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 专家。所以我们只是不知道发生了什么。

谢谢!

4

2 回答 2

5

文档对此不是很清楚,但我认为控制器测试用例类实际上不应该执行引导,因为 PHPUnit 需要能够在每次测试之前执行此操作。至少这是我设置控制器基类(有效)的方式。因此,尝试将您的设置方法更改为:

public function setUp() {
    $this->bootstrap = new Zend_Application(APPLICATION_ENV,
        APPLICATION_PATH . '/configs/application.ini');
    parent::setUp();
}
于 2013-04-04T22:29:10.567 回答
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');

    }

}

之后,将其保存为应用程序/控制器文件夹中的 CommentControllerTest.php。使用终端,导航到控制器文件夹并运行以下命令。

    phpunit CommentControllerTest
于 2015-02-12T09:08:24.697 回答