这是一个关于在Zend Framework 2中使用面向对象代码原理正确编码PHPUnit测试的问题。
我有以下PHPUnit测试用例:
namespace FedcoUserTest;
use FedcoUser'Controller'MachinistController;
class MachinistControllerTest extends Framework'TestCase
{...}
我的MachinistController类是这样的:
namespace FedcoUser'Controller;
class MachinistController extends 'ZfcUser'Controller'UserController
{...}
当尝试运行测试用例时,我会得到以下错误:
Debug Error: MachinistController.php - Class 'ZfcUser'Controller'UserController' not found
这很奇怪,因为我的MachinistController类运行得很好,并且在作为web应用程序运行时找到了ZfcUser的控制器,而不是通过PHPUnit测试。
不知怎么的,我决定放一个
require_once 'vendor/zf-commons/zfc-user/src/ZfcUser/Controller/UserController.php';
行插入我的MachinistControllerTest类,现在我的PHPUnit测试运行时没有错误。
我觉得这很奇怪
为什么:到目前为止,在我使用ZF2的经验中,我还没有使用require
函数的需求。ZF2完全是OO,为什么现在呢?这可能是正确的,但有更好的方法吗?如果有,那是什么?
更具体的问题:
- (正确性)我在代码中使用require_one这一行使测试用例通过是对的吗
- (ZF2最佳实践)为什么我会在我的其他完全OO ZF2代码中使用
require_once()
语句(require
的使用在我看来就像是过程代码的味道) - (OO最佳实践)为什么没有找到ZfcUser的控制器,而我的MachinistController正在完美地扩展它
我最终在TestConfiguration.php文件中的配置中加载了额外的命名空间:
$additionalNamespaces = array(
'ZfcUser'Controller' => __DIR__ . '/../../../vendor/zf-commons/zfc-user/src/ZfcUser/Controller/'
);
它非常适合我的bootstrap.php
,它有以下代码:
// setup autoloader
AutoloaderFactory::factory(
array(
'Zend'Loader'StandardAutoloader' => array(
StandardAutoloader::AUTOREGISTER_ZF => true,
StandardAutoloader::ACT_AS_FALLBACK => false,
StandardAutoloader::LOAD_NS => $additionalNamespaces,
)
)
);
PHPUnit Tests
不是ZF2框架的一部分。ZF2不负责在单元测试文件中自动加载类。
你需要模拟课堂http://phpunit.de/manual/3.6/en/test-doubles.html#test-doubles.mock由您自己创建对象,并负责由您自己要求所有类。
通常,在运行测试之前,您会使用PHPUnit的引导功能来引导应用程序的某些元素(包括自动加载器)。手册中有一个引导程序示例:http://framework.zend.com/manual/2.0/en/user-guide/unit-testing.html.就我个人而言,我使用了一个稍微修改过的版本,它也引入了Composer自动加载器。那么你就不需要在测试中要求任何类了。