使用ZendFramework设置控制器测试:自动加载问题


Setting up a Controller Test with ZendFramework: Autoloader issue

我正在使用Zend Framework v1.11.0的web应用程序,但我未能为控制器测试设置正确的测试环境。我知道已经有很多关于设置Zend测试的问题,然而,经过几个小时的研究,这些都没有解决我的问题。下面是我的代码:

测试引导:

<?php
error_reporting(E_ALL | E_STRICT);
defined('APPLICATION_PATH') || define('APPLICATION_PATH',realpath(dirname(__FILE__).'/../../application'));
define('APPLICATION_ENV', 'testing');
set_include_path(implode(PATH_SEPARATOR, array(realpath(APPLICATION_PATH.'/../library'), get_include_path())));
require_once ('Zend/Application.php');
require_once ('ControllerTestCase.php');

ControllerTestCase:

class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {
  public $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();
  }
}

简单的测试:

class IndexControllerTest extends ControllerTestCase {
    public function testDefaultShouldInvokeIndexAction()
    {
        $this->dispatch('/');
        $this->assertModule('default');
        $this->assertController('index');
        $this->assertAction('index');
    }
}

每次我运行这个测试时,PHPUnit抛出一个致命的错误消息,没有在我的库中找到在我的IndexController中使用的类。因此,我想原因一定与自动装弹机有关。经过调试,我发现,测试通过常规Bootstrap运行,通过Auth插件等,并且我的库包含。所以我不知道PHPUnit的问题可能是什么。在浏览器中,一切都可以正常工作,命令行中的非控制器测试(例如全局设置)也可以工作。

我将非常感谢任何提示,我需要做什么,让我的控制器测试工作!

编辑:我的目录结构是这样的(由于某些原因,我把我的类分成了不同的库)

project
 - library1
 - library2
 - project_name
    ->application
    ->library3
    ->library4
    ->tests
       ->>application
          ->>>ControllerTestCase.php
          ->>>Bootstrap.php
       ->>Controller
          ->>>IndexControllerTest.php

我的include路径实际上是这样的:

set_include_path(implode(PATH_SEPARATOR, array(realpath(APPLICATION_PATH.'/../library3'), get_include_path())));
set_include_path(implode(PATH_SEPARATOR, array(realpath(APPLICATION_PATH.'/../library4'), get_include_path())));
set_include_path(implode(PATH_SEPARATOR, array(realpath(APPLICATION_PATH.'/../../library1'), get_include_path())));
set_include_path(implode(PATH_SEPARATOR, array(realpath(APPLICATION_PATH.'/../../library2'), get_include_path())));

在我自己的ControllerTestCase类中,我在构造函数中设置了bootstrap对象,而不是setUp函数。所以对你来说这意味着改变这个

public function setUp() {
    $this->bootstrap = array($this, 'appBootstrap');
    parent::setUp();
}

public function __construct()
{
    $this->bootstrap = new Zend_Application(
        APPLICATION_ENV,
        APPLICATION_PATH . '/configs/application.ini'
    );
}

和去除appBootstrap方法。这是我看到的你的代码和我自己的代码之间的唯一区别。如果这不能解决问题,很可能是你的路径设置关闭了。

为Zend Controller正确设置测试用例的最简单方法是使用zf工具。通过使用它创建您的控制器,您可以为它们自动生成测试用例。

zf create controller name index-action-included[=1] module

它创建了以下引导:

    defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));
require_once 'Zend/Loader/Autoloader.php';

…controllerTestCase:

class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    public function setUp()
    {
        $this->bootstrap = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
        parent::setUp();
    }
    ....tests.........
}

您必须在引导中添加包含路径,并使用spl_autoloader注册任何自定义测试自动加载器。另外,请记住使用-c test/phpunit.xml

启动phpunit