2010-07-28 5 views
9

У меня есть приложение, которое находится за логином и использует zend_acl и zend_auth.PHP Unit Testing с Zend Auth и Zend ACL

Во время предварительной отправки у меня есть плагин ACL, который создает все правила для ACL. У меня также есть плагин Auth, который проверяет, вошли ли вы в систему или нет, и если это так, если у вас есть доступ к запрашиваемому ресурсу в соответствии с ACL.

Поскольку приложение полностью за логину ACL создается только тогда, когда вы вошли в систему.

Модульное тестирование это оказывается невозможным, или, скорее, скорее всего, я что-то очевидное отсутствует.

В моем методе установки тестового модуля я имитирую успешный логин, который возвращает экземпляр zend_auth. Прошедшие тесты показывают, что этот логин был успешным.

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

Например, это проходит:

public function testLoggedIn() 
{ 
    $this->assertTrue(Zend_Auth::getInstance()->hasIdentity()); 
} 

Это терпит неудачу, как это отвергается плагин:

public function testUserAccess() 
{ 

    $this->dispatch('/home'); 
      $this->assertResponseCode(200); 
      $this->assertQueryContentContains('#nav_side'); 
      $this->resetRequest() 
      ->resetResponse(); 

} 

В этом, я нашел еще, кажется, перенаправление обратно на страницу входа в систему в качестве плагинов не знаю, что пользователь вошел в систему.

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

ответ

3

Проблема, которую вы описываете, очень часто связана с использованием глобальных переменных и глобальной переменной ООП (шаблон Singleton).

Существует статья автором PHPUnit, который описывает, как вы можете избежать этого с помощью Dependency Injection и какие другие возможности у вас есть, и так как это очень описательный, я просто предлагаю вам прочитать :) http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html

Как уродливая альтернатива (если вам нужен быстрый результат), вы можете создать заглушку Zend_Auth (описать в ссылке) и использовать API-интерфейс отражения PHP 5.3, чтобы установить переменную экземпляра Zend_Auth в свою заглушку.

Надежда, что помогает (как вопрос жил 4h без другого ответа)

+0

Да, спасибо, что это проблема. –

2

Вот еще один способ создания заглушки для замены ACL плагина (или любого другого плагина) во время тестирования. Поместите это в свой ControllerTestCase и вызовите его в тестовом примере setUp.

public function doLogin() 
{ 
    // create a fake identity 
    $identity = new stdClass(); 
    $identity->Username = 'PHPUnit'; 
    Zend_Auth::getInstance()->getStorage()->write($identity); 

    // remove the autoloaded plugin 
    $front = Zend_Controller_Front::getInstance(); 
    $front->unregisterPlugin('My_Controller_Plugin_Acl'); 

    // create the stub for the Acl class 
    $mockaAcl = $this->getMock(
     'My_Controller_Plugin_Acl', 
     array('preDispatch'), 
     array(), 
     'My_Controller_Plugin_AclMock' 
    ); 

    // register the stub acl plugin in its place 
    $front->registerPlugin($mockAcl); 
} 

Таким образом, ваш метод заглушкой preDispatch вызывается вместо, который будет обходить ваши фактические проверки контроля доступа.