Соединения CakePHP во время тестирования

В настоящее время я пытаюсь выполнить модульное тестирование некоторого кода. Я выполняю некоторые операторы SQL, введенные вручную, например:

$db = ConnectionManager::get('default');
...
$stmt = $db->prepare($sql);
$stmt->execute();

Я предполагал, что всякий раз, когда я запускаю модульные тесты и запрашиваю соединение default, вместо этого я получаю соединение test. Если он не определен в моей конфигурации, он выдаст исключение. Когда я запускаю тест, который выполняет оператор для базы данных, он всегда выполняется для соединения default. Соединение test никогда не используется.

Любая идея, что я делаю неправильно?

Моя конфигурация базы данных выглядит следующим образом:

'Datasources' => [
    'default' => [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => 'localhost',
        'username' => 'root',
        'password' => '',
        'database' => 'dbname',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
        'quoteIdentifiers' => false,
    ],

    /**
     * The test connection is used during the test suite.
     */
    'test' => [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => 'localhost',
        'username' => 'root',
        'password' => '',
        'database' => 'dbname_test',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
        'quoteIdentifiers' => false,
    ],
]

Спасибо за любую помощь!

Изменить Я думаю, что документация неверна:

По умолчанию CakePHP будет псевдонимом для каждого соединения в вашем приложении. Для каждого соединения, определенного в начальной загрузке вашего приложения, которое не начинается с test_, будет создан псевдоним с префиксом test_. Псевдонимы соединений гарантируют, что вы случайно не используете неправильное соединение в тестовых примерах. Псевдоним соединения прозрачен для остальной части вашего приложения. Например, если вы используете соединение «по умолчанию», вместо этого вы получите тестовое соединение в тестовых случаях. Если вы используете соединение «реплика», набор тестов попытается использовать «test_replica».

Ссылка

Там вы можете прочитать, что CakePHP автоматически применяет псевдоним соединения default к test при выполнении модульных тестов. Чтобы получить такое поведение, вы должны сами определить этот псевдоним в своем phpunit bootstrap.php следующим образом:

\Cake\Datasource\ConnectionManager::alias('test', 'default');

Вы можете прочитать об этом здесь ConnectionManager::alias забавно то, что в документации для alias прямо указано

Например, если вы используете псевдоним «по умолчанию» для «теста», выборка «по умолчанию» всегда будет возвращать «тестовое» соединение, пока псевдоним определен.


person AlexWerz    schedule 20.04.2015    source источник
comment
Конфигурация test используется, когда вы используете ClassRegistry::init для создания экземпляра модели. Когда вы используете ручное соединение, как вы используете, вам нужно вручную получить соединение test. Стоит отметить, что в CakePHP 3.0 соединение default будет привязано к тестовым настройкам, чтобы предотвратить такого рода проблемы.   -  person jeremyharris    schedule 20.04.2015
comment
То, что вы обычно ожидаете, является поведением по умолчанию. Убедитесь, что вы используете правильную конфигурацию PHPUnit и что она включает прослушиватель для CakePHP Fixture Injector, так как именно здесь настраивается псевдоним default => test.   -  person ndm    schedule 20.04.2015
comment
@jeremyharris Этот вопрос касается CakePHP 3.x, который работает по-другому.   -  person ndm    schedule 20.04.2015
comment
@ndm да, я только что заметил это, немного поторопился и получил ваш комментарий, пока редактировал свой оригинал.   -  person jeremyharris    schedule 20.04.2015
comment
@jeremyharris Если соединение default получает псевдоним test, мой код выше должен работать, верно? Или мне нужно получить имя соединения по-другому?   -  person AlexWerz    schedule 21.04.2015
comment
Я решил свою путаницу :-) Вы должны сделать \Cake\Datasource\ConnectionManager::alias('test', 'default'); в своем тестовом бутстрапе. Документация по тестированию в CakePHP говорит мне, что это делается для меня самим CakePHP, но это кажется неверным: Книга CakePHP — Тестирование Они гласят: For example if you use the ‘default’ connection, instead you will get the test connection in test cases.   -  person AlexWerz    schedule 21.04.2015
comment
Нет, это правда, как я уже говорил, это происходит через инжектор фикстур, а точнее в FixtureManager::_aliasConnections(). Вы должны отладить, почему набор тестов, похоже, не доходит до него.   -  person ndm    schedule 21.04.2015
comment
Документы по тестированию, кажется, не учитывают важную часть о создании файла начальной загрузки. Обычно я копирую тестовый бутстрап Cake (и модифицирую) или DebugKit, если работаю над плагином. Поскольку вы не используете приборы, вы не получаете некоторых функций автоматического сглаживания.   -  person jeremyharris    schedule 21.04.2015


Ответы (2)


Псевдоним соединения выполняется по умолчанию, когда вы загружаете прослушиватель менеджера приборов в нашей конфигурации phpunit.xml, поскольку он распространяется в шаблоне приложения:

https://github.com/cakephp/app/blob/master/phpunit.xml.dist#L23-L31

person José Lorenzo Rodríguez    schedule 21.04.2015
comment
Принимая это как ответ. Как отметил @jerremyharris в комментариях выше, документы не учитывают часть создания файла начальной загрузки. - person AlexWerz; 22.04.2015

У нас также была такая же ошибка, для некоторых таблиц тесты получали базу данных по умолчанию вместо тестовой базы данных без всякой причины. В конце концов, использование кода в верхней части функции setUp (до parent::setUp()) решило проблему (у нас есть основной тестовый класс, из которого мы расширяем все тесты, делаем некоторые настройки. Мы помещаем его туда)

TableRegistry::clear();
person Bora Yalcin    schedule 09.08.2017
comment
Большое спасибо, это решение помогло мне тоже! - person Levsha; 13.01.2021