Интеграционный тест Magento 2 в контексте администратора
Я пишу интеграционный тест для Magento 2, где мне нужно эмулировать административную область.
Для этого я использую аннотацию @magentoAppArea
:
/**
* @magentoAppArea adminhtml
*/
Однако некоторые вещи работали не так, как ожидалось, и я обнаружил, что текущий идентификатор магазина установлен на "1" (магазин по умолчанию) вместо "0" (магазин администратора)
Вот минимальный пример неудачного теста:
/**
* @magentoAppArea adminhtml
*/
public function testAdminarea()
{
$storeManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
->get(\Magento\Store\Model\StoreManagerInterface::class);
$this->assertEquals(0, $storeManager->getStore()->getId());
}
Как правильно настроить этот тест?
Что я нашел во время отладки:
Magento\TestFramework\Application::loadArea('adminhtml')
срабатывает правильно.-
Идентификатор магазина сначала инициализируется в
Magento\Store\Model\StoreResolver::getStoresData()
:$cacheKey = 'resolved_stores_' . md5($this->runMode . $this->scopeCode); $cacheData = $this->cache->load($cacheKey);
Где
$this->runMode
- "веб-сайт", а$this->scopeCode
- "ноль".
2 answers
Я думаю, что предположение о том, что хранилище администратора всегда активно в области adminhtml, может больше не соответствовать действительности в Magento 2.
Я нигде не нашел константы с нулевым идентификатором хранилища администратора. Вероятно, это также больше не следует считать таковым.
Состояние приложения и область действия устанавливаются в adminhtml
прослушивателем теста аннотаций, что, вероятно, достаточно для запуска полного поведения серверной части.
Хотя я не уверен. Что вы хотите на самом деле тест?
/**
* @magentoAppArea adminhtml
*/
public function testBackendScopeIsSet()
{
/** @var ObjectManager $objectManager */
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
/** @var \Magento\TestFramework\App\State $state */
$state = $objectManager->get(\Magento\TestFramework\App\State::class);
$this->assertSame(Area::AREA_ADMINHTML, $state->getAreaCode());
/** @var \Magento\Framework\Config\Scope $scope */
$scope = $objectManager->get(\Magento\Framework\Config\Scope::class);
$this->assertSame(Area::AREA_ADMINHTML, $scope->getCurrentScope());
}
Если для вашего теста требуется, чтобы хранилище администратора было активным, вам также потребуется настроить его вручную в разделе "Упорядочить" теста:
/** @var StoreManagerInterface $storeManager */
$storeManager = $objectManager->get(StoreManagerInterface::class);
$storeManager->setCurrentStore(Store::ADMIN_CODE);
$this->assertEquals(0, $storeManager->getStore()->getId());
Я почти уверен, что это должно работать без чего-либо еще.
В основном аннотация @magentoAppArea
определяется в разделе /dev/tests/integration/framework/Magento/TestFramework/Annotation/AppArea.php
, поэтому, если я не уверен, будет ли аннотация работать, если тестовый класс находится под app/code/Vendor/Module/TestFolder
Что делает этот класс, так это повторно инициализирует, а затем загружает указанную вами область:
public function startTest(\PHPUnit_Framework_TestCase $test)
{
$area = $this->_getTestAppArea($test->getAnnotations());
if ($this->_application->getArea() !== $area) {
$this->_application->reinitialize();
if ($this->_application->getArea() !== $area) {
$this->_application->loadArea($area);
}
}
}
Метод loadArea
определен в разделе /dev/tests/integration/framework/Magento/TestFramework/Application.php
и выполняет следующие действия:
- изменить область действия
- перенастроить OM в зависимости от области конфигурация
-
Загрузить область
public function loadArea($areaCode) { $this->_appArea = $areaCode; $scope = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Config\Scope'); $scope->setCurrentScope($areaCode); \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->configure( \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( 'Magento\Framework\App\ObjectManager\ConfigLoader' )->load( $areaCode ) ); $app = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\App\AreaList'); if ($areaCode == \Magento\TestFramework\Application::DEFAULT_APP_AREA) { $app->getArea($areaCode)->load(\Magento\Framework\App\Area::PART_CONFIG); } else { \Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea($areaCode); } }
Возможно, именно здесь вам следует начать отладку.