Установка правильного InvokeArg при выполнении контроллера Zend Framework в жгуте Zend_Test - PullRequest
5 голосов
/ 04 августа 2009

Согласно этому обсуждению списка рассылки, рекомендуемый способ доступа к ресурсам приложения в контроллере Zend MVC:

$this->getInvokeArg('bootstrap')->getResource('foo');

Это работает в производстве (при просмотре на соответствующей веб-странице). Однако при тестировании действия контроллера, содержащего этот код с Zend_Test_PHPUnit_ControllerTestCase, я получаю:

Неустранимая ошибка PHP: вызов функции-члена getResource () для необъекта в ... / application / controllers / IndexController.php в строке 12

До появления этой вещи getInvokeArg тесты выполнялись просто отлично. Вопрос в том, как заставить «рекомендуемый» способ доступа к ресурсам работать в тестовом жгуте?

Только что проверил: $this->getFrontController()->getParam('bootstrap')->getResource('foo') тоже не работает.

ОБНОВЛЕНИЕ: я вызываю загрузчик приложения с помощью phpunit --bootstrap ./scripts/application_bootstrap.php ..., и я знаю, что он работает нормально.

И вот у меня есть:

$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);

$application->bootstrap();

Ответы [ 2 ]

9 голосов
/ 06 августа 2009

Я столкнулся с той же проблемой, когда использовал плагин контроллера, который нуждался в начальной загрузке.

По сути, я создал абстрактный класс и унаследовал от него.


abstract class My_ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
    protected $application;

    public function setUp()
    {


        $this->bootstrap = array($this, 'appBootstrap');


        return parent::setUp();
    }

    public function appBootstrap()
       {

        $this->application = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/config/app.ini');

        $this->application->bootstrap();

        $bootstrap = $this->application->getBootstrap();

        $front = $bootstrap->getResource('FrontController');

        $front->setParam('bootstrap', $bootstrap);

       }
}

Тогда вы используете следующее:


class MyControllerTest extends My_ControllerTestCase
{

}

Я также зарегистрировал запрос, чтобы эта функция стала частью ZF

[ZF-7373]: (http://framework.zend.com/issues/browse/ZF-7373) -

Оставив комментарий, можно выделить это для включения.

4 голосов
/ 04 августа 2009

Редактировать: Извините, я пропустил эту часть вашего вопроса в первый раз (кофе еще нет!). Я отредактировал ответ.

Проблема заключается в том, что Zend_Test_PHPUnit_ControllerTestCase предназначен для контроллеров модульного тестирования. Он пытается использовать очень несколько зависимостей от остальной части фреймворка и НЕ запускает автоматически / bootstrap / что-либо (и не знает) о вашем более крупном приложении.

По сути, getResouce не работает, потому что ваш загрузчик не существует.

Если вы посмотрите вокруг Zend_Test_PHPUnit_ControllerTestCase, вы увидите, что он вручную настраивает и использует Zend_Controller_Front и инициализирует свои собственные объекты запроса / ответа для каждого теста. Он пытается быть как можно большим количеством модульного теста , а не функциональным или интеграционным тестом.

Чтобы решить вашу проблему, вы должны указать тестовому набору , как загрузить приложение. Есть несколько способов добиться этого.

Во-первых, вы можете назначить файл общедоступному свойству bootstrap тестового класса.

public $bootstrap = '/path/to/bootstrap/file.php'

Это хороший вариант для приложений, использующих Zend_Application.

Или, обеспечив обратный вызов свойства bootstrap:

public function setUp()
{
    // Use the 'start' method of a Bootstrap object instance:
    $bootstrap = new Bootstrap('test');
    $this->bootstrap = array($bootstrap, 'start');
    parent::setUp();
}

Примечание: действительно важно вызвать родительский метод setUp, если вы переопределите его.

Редактировать 2: Хорошо, вы фактически загружаете свое приложение. Итак, вы сделали выше, и до сих пор не повезло.

Я бы порекомендовал переопределить метод dispatch TestCase, чтобы убедиться, что он получает загрузчик. (Это сработает наверняка).

public function dispatch($url = null)
{
    $this->getFrontController()->setParam('bootstrap', $yourBootstrap);
    parent::dispatch($url);
}

Если подумать, вы, вероятно, могли бы сделать это и в setUp.

Это позволит тестовому комплекту правильно имитировать поведение фронт-контроллера, созданного с помощью Zend_Application. Теперь оба метода доступа к начальной загрузке должны работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...