PHPUnit无法通过命名空间自动加载找到类


PHPUnit cannot find classes via namespace autoloading

我们有如下简化的文件夹结构:

phpunit.xml
autoloading.php
index.php
/models
    /user
        user.php
        ...
    /settings
        preferences.php
        ...
/tests
    test.php

这是相关文件的内容:

模型/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();
    }
}

模型/设置/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>

测试/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

你知道我们需要改变什么,以便自动加载在测试中也能工作吗?我们已经试了那么多方法,但就是行不通。

谢谢!

我们找到了解决问题的方法:

不再使用我们自己的自动加载。php文件(见上文),我们现在使用psr-4通过composer自动加载。我们的作曲家。Json文件看起来像这样:

{
  "autoload": {
    "psr-4": {
      "models''": "models/"
    }
  }
}

触发composer install后,正在创建包含autoload.php的新文件夹vendor。index.php和phpunit.xml (<phpunit bootstrap="vendor/autoload.php">)中都需要这个文件。

使用这个自动加载设置(同时仍然使用相同的名称空间),一切都可以无缝地工作。