2

У меня возникла проблема с модулем тестирования приложения Zend-Framework в Ubuntu 12.04. Проект-структура является применением Зенда по умолчанию, тогда как модели определяются следующимZF-Autoloader не работает в UnitTests на Ubuntu

./application 
    ./models 
    ./DbTable 
     ./ProjectStatus.php (Application_Model_DbTable_ProjectStatus) 
    ./Mappers 
     ./ProjectStatus.php (Application_Model_Mapper_ProjectStatus) 
    ./ProjectStatus.php (Application_Model_ProjectStatus) 

Проблемы здесь с Zend специфичной автозагрузкой. Соглашение об именах здесь показывает, что папка Mappers загружает все классы с помощью _Mapper, но не _Mappers. Это некоторое внутреннее поведение Zend, которое до сих пор прекрасно.

На моем компьютере с Windows phpunit работает без проблем, пытаясь инициировать все эти классы.

На моей машине Ubuntu, однако с Дженкинс работает на нем, PHPUnit не удается найти соответствующие классы давая мне следующее сообщение об ошибке появляется

Fatal error: Class 'Application_Model_Mapper_ProjectStatus' not found 
in /var/lib/jenkins/jobs/PAM/workspace/tests/application/models/Mapper/ProjectStatusTest.php 
on line 39 

ошибки, чтобы быть действительно что Зенд-автозагрузчик не загружается из машина ubuntu, но я не могу понять, как и почему это работает. Остается вопрос, почему это так. Я думаю, что я дважды проверял каждую точку контакта с автозагрузкой zend, но я просто не могу понять это. Я вложу - с моей точки зрения соответствующие фрагменты - и надеюсь, что у кого-то из вас есть понимание этого.

Дженкинс Сниппет для РНРипхЬ

<target name="phpunit" description="Run unit tests with PHPUnit"> 
    <exec executable="phpunit" failonerror="true"> 
    <arg line="--configuration '${basedir}/tests/phpunit.xml' --coverage-clover '${basedir}/build/logs/clover.xml' --coverage-html '${basedir}/build/coverage/.' --log-junit '${basedir}/build/logs/junit.xml'" /> 
    </exec> 
</target> 

./tests/phpunit.xml

<phpunit bootstrap="./bootstrap.php"> 
    ... this shouldn't be of relevance ... 
</phpunit> 

./tests/bootstrap.php

<?php 
// Define path to application directory 
defined('APPLICATION_PATH') 
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 

// Define application environment 
defined('APPLICATION_ENV') 
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing')); 

// Ensure library/ is on include_path 
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'), 
    get_include_path(), 
))); 

require_once 'Zend/Loader/Autoloader.php';  
Zend_Loader_Autoloader::getInstance(); 

Любая помощь будет оценена по достоинству.

ответ

2

Я действительно думаю, что проблема связана с вашей папкой «models/Mappers». Это должны быть «модели/мапперы» (все строчные буквы), и объяснил бы, почему он работает на Windows, а не на Linux.

Как видно из класса Zend_Application_Module_Autoloader:

$this->addResourceTypes(array(
      'dbtable' => array(
       'namespace' => 'Model_DbTable', 
       'path'  => 'models/DbTable', 
      ), 
      'mappers' => array(
       'namespace' => 'Model_Mapper', 
       'path'  => 'models/mappers', 
      ), 

Однако, согласно моему предыдущему ответу, я до сих пор считаю, что вам нужно будет грузиться приложение для всех ресурсов по умолчанию, которые будут добавлены автоматически

+0

Это то, к чему это сводилось. Windows Да, Unix Нет, должно было привести меня к нечувствительности к регистру напрямую ... Спасибо, что указали это. И нет, приложение не нужно загружать в моем случае. Для тестирования моделей нет необходимости загружать приложение, автозагрузчика достаточно. Для тестирования контроллеров я загружаю приложение перед тем, как сам тест будет готов к чистому «одинокому» приложению. **Еще раз спасибо!** – Sam

1

Из Руководства ZF:

Создание модели и базы данных таблицы

Перед тем, как приступить к работе, давайте рассмотрим что-то: где будут жить эти классы, и как мы находим их? Созданный по умолчанию проект создает экземпляр автозагрузчика . Мы можем присоединить к нему другие автозагрузчики, чтобы он знал , где можно найти разные классы. Обычно мы хотим, чтобы наши различные классы MVC сгруппированы под одним и тем же деревом - в данном случае - приложение/- и чаще всего используют общий префикс.

Zend_Controller_Front имеет понятие «модули», которые являются индивидуальными мини-приложениями. Модули имитируют структуру каталогов, которую устанавливает инструмент zf в приложении /, а все классы внутри них - , предположительно начинающиеся с общего префикса - имени модуля. application/ - сам модуль - модуль «по умолчанию» или «приложение». Таким образом, мы хотим настроить автозагрузку для ресурсов в этом каталоге.

Zend_Application_Module_Autoloader обеспечивает функциональность, необходимую для сопоставления различных ресурсов в рамках модуля к соответствующим каталогам, и обеспечивает стандартный механизм именования, а также. Экземпляр класса создается по умолчанию при инициализации объекта начальной загрузки ; ваш загрузочный файл приложения по умолчанию будет использовать префикс модуля «Приложение». Таким образом, наши классы, формы и таблицы начнут с префикса класса «Application_».

С Zend_Application_Module_Autoloader загружаются по умолчанию, вы должны только для начальной загрузки приложения (вам не придется запускать фронт-контроллер) согласно примеру на этот ответ.

Если вы не хотите, чтобы самонастройки приложения, вы можете закоротить загрузка ресурсов по инициализации Zend_Application_Module_Autoloader себя:

$autoloader = new Zend_Application_Module_Autoloader(); 

Как вы можете видеть из кода, то __construct этого класса вызывает initDefaultResourceTypes (), со всеми лакомства вы ищете:

class Zend_Application_Module_Autoloader extends Zend_Loader_Autoloader_Resource 
{ 
    /** 
    * Constructor 
    * 
    * @param array|Zend_Config $options 
    * @return void 
    */ 
    public function __construct($options) 
    { 
     parent::__construct($options); 
     $this->initDefaultResourceTypes(); 
    } 

    /** 
    * Initialize default resource types for module resource classes 
    * 
    * @return void 
    */ 
    public function initDefaultResourceTypes() 
    { 
     $basePath = $this->getBasePath(); 
     $this->addResourceTypes(array(
      'dbtable' => array(
       'namespace' => 'Model_DbTable', 
       'path'  => 'models/DbTable', 
      ), 
      'mappers' => array(
       'namespace' => 'Model_Mapper', 
       'path'  => 'models/mappers', 
      ), 
      'form' => array(
       'namespace' => 'Form', 
       'path'  => 'forms', 
      ), 
      'model' => array(
       'namespace' => 'Model', 
       'path'  => 'models', 
      ), 
      'plugin' => array(
       'namespace' => 'Plugin', 
       'path'  => 'plugins', 
      ), 
      'service' => array(
       'namespace' => 'Service', 
       'path'  => 'services', 
      ), 
      'viewhelper' => array(
       'namespace' => 'View_Helper', 
       'path'  => 'views/helpers', 
      ), 
      'viewfilter' => array(
       'namespace' => 'View_Filter', 
       'path'  => 'views/filters', 
      ), 
     )); 
     $this->setDefaultResourceType('model'); 
    } 
} 

для только начальной загрузки приложения без запуска фронт-контроллера в тестах/bootstrap.php:

<?php 
// Define path to application directory 
defined('APPLICATION_PATH') 
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 

// Define application environment 
defined('APPLICATION_ENV') 
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing')); 

// Ensure library/ is on include_path 
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'), 
    get_include_path(), 
))); 

require_once 'Zend/Loader/Autoloader.php'; 

$config = array(
    APPLICATION_PATH . '/configs/application.ini' 
); 

// Create application, bootstrap, and run 
$application = new Zend_Application(
    APPLICATION_ENV, 
    array('config' => $config) 
); 

$application->bootstrap(); 
+0

Не работает. Сначала необходимо запустить автозагрузчик, но классы под папкой Mappers не найдены. Однако я нашел рабочее решение, которое я собираюсь добавить. Однако для меня остается загадкой, почему происходит сфокусировка ... – Sam

0

Поскольку обычный автозагрузчик не работал, я попытался вручную сделать то, что сделает любое приложение Zend. Вот bootstrap.php, что выработанная в конце

<?php  
// Define path to application directory 
defined('APPLICATION_PATH') 
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 

// Define application environment 
defined('APPLICATION_ENV') 
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing')); 

// Ensure library/ is on include_path 
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'), 
    get_include_path(), 
))); 

require_once 'Zend/Loader/Autoloader.php'; 
require_once 'Zend/Loader/Autoloader/Resource.php'; 
$resources = new Zend_Loader_Autoloader_Resource(array(
    'namespace' => 'Application', 
    'basePath' => APPLICATION_PATH 
)); 

$resources->addResourceType('form','forms','Form'); 
$resources->addResourceType('model','models','Model'); 
$resources->addResourceType('dbtable','models/DbTable','Model_DbTable'); 
$resources->addResourceType('mapper','models/Mappers','Model_Mapper'); 

Логика обычно является то, что Zend должен выяснить самостоятельно. И на самом деле это делается на моей локальной машине разработки, работающей на окнах. Однако на ubuntu мне нужно стать конкретным.

Было бы интересно узнать, почему это так. Если кто-то может объяснить мне аргументы, я, вероятно, в конечном итоге дам вам правильный ответ;)

 Смежные вопросы

  • Нет связанных вопросов^_^