Подтвердить что ты не робот

Аутентификация по модулю тестирования ZF2

Я изучал модульное тестирование, и я попытался решить следующую проблему:

Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for zfcUserAuthentication

... используя единственный ответ, указанный в:

Простые тесты ZF2 для контроллера с использованием ZfcUser

Итак, моя функция setUp выглядит одинаково. К сожалению, я получаю сообщение об ошибке:

Zend\Mvc\Exception\InvalidPluginException: Plugin of type Mock_ZfcUserAuthentication_868bf824 is invalid; must implement Zend\Mvc\Controller\Plugin\PluginInterface

Это вызвано в этой части кода (разделить мой код таким же образом):

$this -> controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock); // Error refers to this line.

Объект $authMock, по-видимому, не реализует plugininterface, который мне нужно реализовать, чтобы перейти в setService.

Является ли $authMock не предназначен для передачи там для использования в модульном тестировании? Должен ли я использовать другой метод setService, ориентированный на единичное тестирование?

Мне нужен способ обработки регистрации в моем приложении, или мое модульное тестирование бессмысленно.

Спасибо за любой совет.

=== Редактировать (11/02/2013) ===

Я хотел сосредоточиться на этой части для разъяснения, поскольку я думаю, что это проблемная область:

// Getting mock of authentication object, which is used as a plugin.
$authMock = $this->getMock('ZfcUser\Controller\Plugin\ZfcUserAuthentication');

// Some expectations of the authentication service.
$authMock   -> expects($this->any())
    -> method('hasIdentity')
    -> will($this->returnValue(true));  

$authMock   -> expects($this->any())
    -> method('getIdentity')
    -> will($this->returnValue($ZfcUserMock));

// At this point, PluginManager disallows mock being assigned as plugin because 
// it will not implement plugin interface, as mentioned.
$this -> controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock);

Если макет не обрабатывает необходимые реализации, как еще мне притворяться, чтобы войти в систему?

4b9b3361

Ответ 1

У вас возникла проблема с расширением имени или автозагрузчиком.

Когда вы создаете свой макет, определение класса ZfcUser\Controller\Plugin\ZfcUserAuthentication не найдено. Таким образом, PHPUnit создает макет, который расширяет этот класс только для вашего теста. Если класс был доступен, то PHPUnit будет использовать фактический класс для расширения при создании своего макета, который затем будет использовать родительские классы/интерфейсы.

Здесь вы можете увидеть эту логику: https://github.com/sebastianbergmann/phpunit-mock-objects/blob/master/PHPUnit/Framework/MockObject/Generator.php

    if (!class_exists($mockClassName['fullClassName'], $callAutoload) &&
        !interface_exists($mockClassName['fullClassName'], $callAutoload)) {
        $prologue = 'class ' . $mockClassName['originalClassName'] . "\n{\n}\n\n";

        if (!empty($mockClassName['namespaceName'])) {
            $prologue = 'namespace ' . $mockClassName['namespaceName'] .
                        " {\n\n" . $prologue . "}\n\n" .
                        "namespace {\n\n";

            $epilogue = "\n\n}";
        }

        $cloneTemplate = new Text_Template(
          $templateDir . 'mocked_clone.tpl'
        );

Итак, если нет класса или интерфейса, PHPUnit фактически создаст сам, так что макет будет соответствовать типу, намекающему на исходное имя класса. Однако любые родительские классы или интерфейсы не будут включены, потому что PHPUnit не знает о них.

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


Альтернативно вместо того, чтобы насмехаться ZfcUser\Controller\Plugin\ZfcUserAuthentication, вы можете издеваться над Zend\Mvc\Controller\Plugin\PluginInterface в своем тесте и передать это в диспетчер плагинов. Хотя, если вы указали тип плагина для своего кода, ваш тест все равно не будет работать.

//Mock the plugin interface for checking authorization
$authMock = $this->getMock('Zend\Mvc\Controller\Plugin\PluginInterface');

// Some expectations of the authentication service.
$authMock   -> expects($this->any())
    -> method('hasIdentity')
    -> will($this->returnValue(true));  

$authMock   -> expects($this->any())
    -> method('getIdentity')
    -> will($this->returnValue($ZfcUserMock));

$this -> controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock);

Ответ 2

Я просто сделал пример для плагина FlashMessenger. Вы должны просто использовать ControllerPluginManager для переопределения ControllerPlugin. Убедитесь, что ваша загрузочная загрузка приложения вызывает setApplicationConfig();

<?php
namespace SimpleTest\Controller;

use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;

class SimpleControllerTest extends AbstractHttpControllerTestCase {

  public function testControllerWillAddErrorMessageToFlashMessenger()
  {
      $flashMessengerMock = $this->getMockBuilder('\Zend\Mvc\Controller\Plugin\FlashMessenger', array('addErrorMessage'))->getMock();
      $flashMessengerMock->expects($this->once())
          ->method('addErrorMessage')
          ->will($this->returnValue(array()));


      $serviceManager = $this->getApplicationServiceLocator();
      $serviceManager->setAllowOverride(true);
      $serviceManager->get('ControllerPluginManager')->setService('flashMessenger', $flashMessengerMock);

      $this->dispatch('/error/message');

  }
}?>