根据this邮件列表讨论,访问Zend MVC控制器中的应用程序资源的推荐方法是:
$this->getInvokeArg('bootstrap')->getResource('foo');
这适用于制作(浏览到相应的网页时)。但是,在使用Zend_Test_PHPUnit_ControllerTestCase
测试包含此代码的控制器操作时,我得到:
PHP致命错误:在第12行的... / application / controllers / IndexController.php中的非对象上调用成员函数getResource()
在介绍getInvokeArg
之前,测试运行得很好。问题是,如何在测试工具中使用“推荐”的方式访问资源?
刚检查:$this->getFrontController()->getParam('bootstrap')->getResource('foo')
也不起作用。
更新:我用phpunit --bootstrap ./scripts/application_bootstrap.php ...
调用应用程序引导程序,我知道它执行正常。
我有:
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap();
答案 0 :(得分:9)
当使用需要引导程序的控制器插件时,我遇到了同样的问题。
基本上我创建了一个抽象类并从中继承。
abstract class My_ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
protected $application;
public function setUp()
{
$this->bootstrap = array($this, 'appBootstrap');
return parent::setUp();
}
public function appBootstrap()
{
$this->application = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/config/app.ini');
$this->application->bootstrap();
$bootstrap = $this->application->getBootstrap();
$front = $bootstrap->getResource('FrontController');
$front->setParam('bootstrap', $bootstrap);
}
}
然后使用如下:
class MyControllerTest extends My_ControllerTestCase
{
}
我还记录了一个请求,让此功能成为ZF的一部分
[ZF-7373] :( http://framework.zend.com/issues/browse/ZF-7373) -
发表评论有助于强调这一点。
答案 1 :(得分:4)
编辑:对不起,我第一次错过了你的问题部分(还没有咖啡!)。我已经编辑了答案。
问题在于Zend_Test_PHPUnit_ControllerTestCase
是指单元测试控制器。它试图从框架的其余部分使用非常的几个依赖项,它不会自动运行/ bootstrap /任何(并且不知道)你的大型应用程序。
基本上,getResouce
不起作用,因为你的引导程序不存在。
如果您浏览Zend_Test_PHPUnit_ControllerTestCase
,您会看到它手动设置并使用Zend_Controller_Front
,并为每个测试初始化自己的请求/响应对象。它试图尽可能多地进行单元测试,而不是功能测试或集成测试。
要解决您的问题,您必须告诉测试套件如何来引导您的应用程序。有几种方法可以实现这一目标。
一,您可以将文件分配给测试类的公共bootstrap
属性。
public $bootstrap = '/path/to/bootstrap/file.php'
对于使用Zend_Application
的应用程序,这是一个不错的选择。
或者,通过向bootstrap
属性提供回调:
public function setUp()
{
// Use the 'start' method of a Bootstrap object instance:
$bootstrap = new Bootstrap('test');
$this->bootstrap = array($bootstrap, 'start');
parent::setUp();
}
注意:如果覆盖它,则调用父setUp
方法非常重要。
编辑2:好的, 实际上是在引导你的应用程序。所以,你已经完成了上述工作,但仍然没有运气。
我建议覆盖TestCase的dispatch
方法,以确保它正在接收引导程序。 (这肯定会起作用。)
public function dispatch($url = null)
{
$this->getFrontController()->setParam('bootstrap', $yourBootstrap);
parent::dispatch($url);
}
想想看,你也可以在setUp
中做到这一点。
这将允许测试套件正确模仿由Zend_Application
构造的前端控制器的行为。访问引导程序的两种方法现在都可以使用。