PHPUnit не может найти классы через автозагрузку пространства имен

У нас есть следующая упрощенная структура папок:

phpunit.xml
autoloading.php
index.php

/models
    /user
        user.php
        ...

    /settings
        preferences.php
        ...

/tests
    test.php

Это содержимое соответствующих файлов:

модели / пользователь / 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();
    }
}

модели / настройки / предпочтенияs.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, а не через композитор), которые также используют тот же механизм автозагрузки:

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

Есть идеи, что нам нужно изменить, чтобы автозагрузка работала и в тестах? Мы столько всего перепробовали, но ничего не вышло.

Спасибо!


person Lionel    schedule 12.07.2015    source источник


Ответы (1)


Мы нашли способ решения нашей проблемы:

Вместо использования нашего собственного файла autoloading.php (см. Выше) мы теперь используем автозагрузку psr-4 через композитор. Наш файл composer.json выглядит так:

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

После запуска composer install создается новая папка vendor, содержащая autoload.php. Этот файл может потребоваться как в index.php, так и в phpunit.xml (<phpunit bootstrap="vendor/autoload.php">).

С такой настройкой автозагрузки (с использованием тех же пространств имен) все работает без проблем.

person Lionel    schedule 13.07.2015
comment
да, я знаю, что это старый, но это сработало на 100% и заняло 2 минуты то, что я пытался решить в течение 4 часов! - person imposterSyndrome; 14.08.2019