2015-01-29 3 views
2

У меня есть следующий InputFilter:PHPUnit ZF2 InputFilter с валидатора

<?php 

namespace Login\InputFilter; 

use Zend\InputFilter\InputFilter; 

/** 
* Class Login 
* 
* @package Login\InputFilter 
*/ 
class Login extends InputFilter 
{ 
    /** 
    * Construct 
    */ 
    public function __construct() 
    { 
     /** 
     * Password 
     */ 
     $this->add(
      [ 
       'name'  => 'password', 
       'required' => true, 
       'filters' => [ 
        [ 
         'name' => 'stringtrim' 
        ] 
       ], 
       'validators' => [ 
        [ 
         'name'     => 'stringlength', 
         'options'    => [ 
          'min' => '5', 
          'max' => '128' 
         ], 
         'break_chain_on_failure' => true 
        ], 
        [ 
         'name'     => 'regex', 
         'options'    => [ 
          'pattern' => '/^[^\\\' ]+$/' 
         ], 
         'break_chain_on_failure' => true 
        ] 
       ] 
      ] 
     ); 
    } 

    /** 
    * Init 
    */ 
    public function init() 
    { 
     /** 
     * Employee ID 
     */ 
     $this->add(
      [ 
       'name'  => 'employeeId', 
       'required' => true, 
       'filters' => [ 
        [ 
         'name' => 'stringtrim' 
        ] 
       ], 
       'validators' => [ 
        [ 
         'name'     => 'stringlength', 
         'options'    => [ 
          'min' => '1', 
          'max' => '20' 
         ], 
         'break_chain_on_failure' => true 
        ], 
        [ 
         'name'     => 'digits', 
         'break_chain_on_failure' => true 
        ], 
        [ 
         'name'     => 'Login\Validator\EmployeeId', 
         'break_chain_on_failure' => true 
        ] 
       ] 
      ] 
     ); 
    } 
} 

Прикрепленный к employeeId является валидатора я создал, чтобы проверить, если Employee ID на самом деле существует в базе данных. Он имеет конструктор для Doctrine Entity Manager. Это отлично работает при тестировании через Интернет, поэтому не стоит беспокоиться.

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

<?php 

namespace LoginTest\InputFilter; 

use Login\InputFilter\Login; 

/** 
* Class LoginTest 
* 
* @package LoginTest\InputFilter 
*/ 
class LoginTest extends \PHPUnit_Framework_TestCase 
{ 
    /** 
    * @var Login $inputFilter 
    */ 
    protected $inputFilter; 

    public function setUp() 
    { 
     $this->inputFilter = new Login(); 

     $this->inputFilter->init(); 

     parent::setUp(); 
    } 

    public function testFormHasElements() 
    { 
     $inputs = $this->inputFilter->getInputs(); 

     $this->assertArrayHasKey(
      'employeeId', 
      $inputs 
     ); 

     $this->assertArrayHasKey(
      'password', 
      $inputs 
     ); 
    } 
} 

Когда тест запускается производится следующее сообщение об ошибке:

1) LoginTest\InputFilter\LoginTest::testFormHasElements 
Argument 1 passed to Login\Validator\EmployeeId::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in /vhosts/admin-application/vendor/zendframework/zendframework/library/Zend/ServiceManager/AbstractPluginManager.php on line 180 and defined 

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

Валидатор имеет фабрику, которая снабжает диспетчера объектов Doctrine из локатора сервисов.

Я все еще очень новичок в PHPUnit, но я пытался сделать свое исследование, прежде чем спрашивать здесь.

Любые идеи?

ответ

3

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

В реальном приложении InputFilter использует Zend\Validator\ValidatorPluginManager для получения валидаторов от сервис-менеджера.

Я вижу два пути, как решить эту проблему:

1.) Вы можете менеджер настройки реальной службы от конфигурации приложения, как это описано в documentation, а затем потянуть входной фильтр от менеджера службы:

$inputFilter = Bootstrap::getServiceManager()->get(\Login\InputFilter\Login::class); // change the service name if you have another 

Это решение хорошо, если вы хотите написать какие-либо интеграционные тесты.

2.) Вы можете издеваться свой собственный валидатор и впрыснуть в ValidatorPluginManager в методе установки:

protected function setUp() 
{ 
    $validator = $this->getMockBuilder(\Login\Validator\EmployeeId::class)->getMock(); 

    $inputFilter = new Login(); 
    $inputFilter->getFactory() 
     ->getDefaultValidatorChain() 
     ->getPluginManager() 
     ->setService(\Login\Validator\EmployeeId::class, $validator); 
    $inputFilter->init(); 

    $this->inputFilter = $inputFilter; 

    parent::setUp(); 
} 

Это решение хорошо, если вы хотите написать модульные тесты для Логин входного фильтра.

+0

Благодарим вас за подробное объяснение. То, что вы упомянули, имеет большой смысл, и это вернуло меня в нужное русло. Единственное, что я добавил к вашему примеру, - это $ validator, необходимый для того, чтобы '-> disableOriginalConstructor()' для изделенного объекта – Diemuzi

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