PHPUnit 无法通过命名空间自动加载找到 类
PHPUnit cannot find classes via namespace autoloading
我们有以下简化的文件夹结构:
phpunit.xml
autoloading.php
index.php
/models
/user
user.php
...
/settings
preferences.php
...
/tests
test.php
这是相关文件的内容:
models/user/user.php
namespace models\user;
class User {
private $preferences;
public function __construct()
{
$this->preferences = new \models\settings\Preferences();
}
public function getPreferenceType()
{
return $this->preferences->getType();
}
}
models/settings/preferences.php
namespace models\settings;
class Preferences {
private $type;
public function __construct($type = 'default')
{
$this->type = $type;
}
public function getType()
{
return $this->type;
}
}
autoloading.php
spl_autoload_extensions('.php');
spl_autoload_register();
index.php
require_once 'autoloading.php';
$user = new \models\user\User();
echo $user->getPreferenceType();
当我们 运行 index.php 时,通过命名空间 自动 自动加载一切正常。由于命名空间适合文件夹结构,所有内容都会自动加载。
我们现在想设置一些 PHPUnit 测试(通过 phpunit.phar,而不是 composer),它们也使用相同的自动加载机制:
phpunit.xml
<phpunit bootstrap="autoloading.php">
<testsuites>
<testsuite name="My Test Suite">
<file>tests/test.php</file>
</testsuite>
</testsuites>
</phpunit>
tests/test.php
class Test extends PHPUnit_Framework_TestCase
{
public function testAccess()
{
$user = new \models\user\User();
$this->assertEquals('default', $user->getPreferenceType());
}
}
当我们运行测试时,我们得到以下错误:
Fatal error: Class 'models\user\User' not found in tests\test.php on line 7
我们当然可以在测试中添加以下方法:
public function setup()
{
require_once '../models/user/user.php';
}
但是会出现如下错误等:
Fatal error: Class 'models\settings\Preferences' not found in models\user\user.php on line 11
知道我们必须更改什么以便自动加载在测试中也能正常工作吗?我们试了很多东西,就是不行。
谢谢!
我们找到了解决问题的方法:
我们现在使用 psr-4 通过 composer 自动加载,而不是使用我们自己的 autoloading.php 文件(见上文)。我们的 composer.json 文件如下所示:
{
"autoload": {
"psr-4": {
"models\": "models/"
}
}
}
触发 composer install
后,正在创建一个新文件夹 vendor
,其中包含 autoload.php
。在 index.php 和 phpunit.xml (<phpunit bootstrap="vendor/autoload.php">
) 中可能需要此文件。
有了这个自动加载设置(同时仍然使用相同的命名空间),一切都可以无缝运行。
我们有以下简化的文件夹结构:
phpunit.xml
autoloading.php
index.php
/models
/user
user.php
...
/settings
preferences.php
...
/tests
test.php
这是相关文件的内容:
models/user/user.php
namespace models\user;
class User {
private $preferences;
public function __construct()
{
$this->preferences = new \models\settings\Preferences();
}
public function getPreferenceType()
{
return $this->preferences->getType();
}
}
models/settings/preferences.php
namespace models\settings;
class Preferences {
private $type;
public function __construct($type = 'default')
{
$this->type = $type;
}
public function getType()
{
return $this->type;
}
}
autoloading.php
spl_autoload_extensions('.php');
spl_autoload_register();
index.php
require_once 'autoloading.php';
$user = new \models\user\User();
echo $user->getPreferenceType();
当我们 运行 index.php 时,通过命名空间 自动 自动加载一切正常。由于命名空间适合文件夹结构,所有内容都会自动加载。
我们现在想设置一些 PHPUnit 测试(通过 phpunit.phar,而不是 composer),它们也使用相同的自动加载机制:
phpunit.xml
<phpunit bootstrap="autoloading.php">
<testsuites>
<testsuite name="My Test Suite">
<file>tests/test.php</file>
</testsuite>
</testsuites>
</phpunit>
tests/test.php
class Test extends PHPUnit_Framework_TestCase
{
public function testAccess()
{
$user = new \models\user\User();
$this->assertEquals('default', $user->getPreferenceType());
}
}
当我们运行测试时,我们得到以下错误:
Fatal error: Class 'models\user\User' not found in tests\test.php on line 7
我们当然可以在测试中添加以下方法:
public function setup()
{
require_once '../models/user/user.php';
}
但是会出现如下错误等:
Fatal error: Class 'models\settings\Preferences' not found in models\user\user.php on line 11
知道我们必须更改什么以便自动加载在测试中也能正常工作吗?我们试了很多东西,就是不行。
谢谢!
我们找到了解决问题的方法:
我们现在使用 psr-4 通过 composer 自动加载,而不是使用我们自己的 autoloading.php 文件(见上文)。我们的 composer.json 文件如下所示:
{
"autoload": {
"psr-4": {
"models\": "models/"
}
}
}
触发 composer install
后,正在创建一个新文件夹 vendor
,其中包含 autoload.php
。在 index.php 和 phpunit.xml (<phpunit bootstrap="vendor/autoload.php">
) 中可能需要此文件。
有了这个自动加载设置(同时仍然使用相同的命名空间),一切都可以无缝运行。