Модульное тестирование PHP с Zend Auth и Zend ACL - PullRequest
10 голосов
/ 28 июля 2010

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

Во время предварительной отправки у меня есть плагин 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();

 }

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

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

Ответы [ 2 ]

4 голосов
/ 30 января 2012

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

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 заглушки, который пропустит фактические проверки контроля доступа.

3 голосов
/ 28 июля 2010

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

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

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

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

...