2016-08-22 3 views
0

Я пишу тест в PHPSpec 2.0.0, который использовал бы конструктор запросов Doctrine в приложении Symfony. Это мой класс:phsspec doctrine queryBuilder - mock

class RedirectHandle 
{ 
    /** 
    * @var string 
    */ 
    private $kernelEnvironment; 

    /** 
    * @var ContainerInterface 
    */ 
    private $container; 

    /** 
    * RedirectHandle constructor. 
    * @param $env 
    * @param ContainerInterface $containerInterface 
    */ 
    public function __construct($env, ContainerInterface $containerInterface) 
    { 
     $this->kernelEnvironment = $env; 
     $this->container = $containerInterface; 
    } 

    public function handleUrl($url) 
    { 
     if ($this->kernelEnvironment === "dev") { 
      $em = $this->container->get("doctrine")->getEntityManager(); 
      return $em->createQuery("SELECT a FROM module_redirect a WHERE url_from_redirect = :url ") 
       ->setParameter('url', $url) 
       ->getSingleScalarResult(); 
     } 
     return false; 
    } 
} 

Вот мой phpspec тест:

class RedirectHandleSpec extends ObjectBehavior 
{ 
    function let($kernel,$container,$queryBuilder,$em,$redirectHandle) 
    { 
     $env = "dev"; 
     $kernel->beADoubleOf('Symfony\Component\HttpKernel\Kernel'); 
     $kernel->getEnvironment()->willReturn($env); 
     $queryBuilder->beADoubleOf('Doctrine\ORM\QueryBuilder'); 
     $container->beADoubleOf('Symfony\Component\DependencyInjection\ContainerInterface'); 
     $redirectHandle->beADoubleOf('Kei\WebsiteBundle\Tools\Redirect\RedirectHandle'); 
     $em->beADoubleOf('Doctrine\ORM\EntityManager'); 
     $kernel->getContainer()->willReturn($container); 
     $this->beConstructedWith($env,$container); 
    } 

    function it_is_initializable() 
    { 
     $this->shouldHaveType('Kei\WebsiteBundle\Tools\Redirect\RedirectHandle'); 
    } 

    function it_is_init_redirect_when_env_is_dev($container,$queryBuilder,$em) 
    { 
     $container->get("doctrine")->willReturn($queryBuilder); 
     $em->createQuery(Argument::any())->willReturn($em); 
     $this->handleUrl("test")->shouldBeReturn(true); 
    } 
} 

Когда я побежал тест, я получил следующее сообщение об ошибке:

1PHP Fatal error: Uncaught Error: Call to a member function createQuery() on null in /var/www/kei-site/src/Kei/WebsiteBundle/Tools/Redirect/RedirectHandle.php:37 
Stack trace: 
#0 [internal function]: Kei\WebsiteBundle\Tools\Redirect\RedirectHandle->handleUrl('test') 
#1 /var/www/kei-site/vendor/phpspec/phpspec/src/PhpSpec/Wrapper/Subject/Caller.php(260): call_user_func_array(Array, Array) 
#2 /var/www/kei-site/vendor/phpspec/phpspec/src/PhpSpec/Wrapper/Subject/Caller.php(97): PhpSpec\Wrapper\Subject\Caller->invokeAndWrapMethodResult(Object(Kei\WebsiteBundle\Tools\Redirect\RedirectHandle), 'handleUrl', Array) 
#3 /var/www/kei-site/vendor/phpspec/phpspec/src/PhpSpec/Wrapper/Subject.php(187): PhpSpec\Wrapper\Subject\Caller->call('handleUrl', Array) 
#4 [internal function]: PhpSpec\Wrapper\Subject->__call('handleUrl', Array) 
#5 /var/www/kei-site/vendor/phpspec/phpspec/src/PhpSpec/ObjectBehavior.php(136): call_user_func_array(Array, Array) 
#6 /var/www/kei-site/spec/Kei/WebsiteBundle/Tools/Redirect/RedirectHandleSpec.php(40): PhpSpec\Obj in /var/www/kei-site/src/Kei/WebsiteBundle/Tools/Redirect/RedirectHandle.php on line 37 

Что я должен сделать, чтобы исправить это?

+0

Не могли бы Вы реорганизовать свой код, чтобы избавиться от службы локатора шаблон? Не вводите весь контейнер, а только тот сервис, который вам действительно нужен. Начните с теста для этого, и вы увидите, как все стало проще. Inject репозиторий, который будет иметь запрос, который вы строите. – mmmm

+0

«Не могли бы вы реорганизовать свой код, чтобы избавиться от шаблона локатора службы?» Не возражаете ли вы от phpspec? Я должен удалить «$ container-> get (« doctrine ») -> willReturn ($ queryBuilder)»? –

+0

Нет, из класса 'RedirectHandle'. Внесите туда то, что я написал, это сделает его более чистым и более легким для тестирования. – mmmm

ответ

0
class RedirectHandle 
{ 
    /** 
    * @var string 
    */ 
    private $kernelEnvironment; 
    /** 
    * @var 
    */ 
    private $container; 

    /** 
    * RedirectHandle constructor. 
    * @param $env 
    * @param ContainerInterface $containerInterface 
    */ 
    public function __construct($env,ContainerInterface $containerInterface) 
    { 
     $this->kernelEnvironment = $env; 
     $this->container = $containerInterface; 
    } 

    /** 
    * 
    */ 
    public function handleUrl($url) 
    { 

     if ($this->kernelEnvironment === "dev") { 
      $em = $this->container->get("doctrine")->getEntityManager(); 
      $query = $em->createQuery("SELECT a FROM KeiWebsiteBundle:Carrier a"); 
      return true; 
     } 
     return false; 
    } 
} 

Phpspec код после того, как реорганизовать:

класс расширяет RedirectHandleSpec ObjectBehavior {

function let($kernel,$container,$queryBuilder,$em) 
{ 
    $env = "dev"; 
    $kernel->beADoubleOf('Symfony\Component\HttpKernel\Kernel'); 
    $queryBuilder->beADoubleOf('Doctrine\ORM\QueryBuilder'); 
    $container->beADoubleOf('Symfony\Component\DependencyInjection\ContainerInterface'); 
    $em->beADoubleOf('Doctrine\ORM\EntityManager'); 
    $this->beConstructedWith($env,$container); 
} 
function it_is_initializable() 
{ 
    $this->shouldHaveType('Kei\WebsiteBundle\Tools\Redirect\RedirectHandle'); 
} 

/** 
* Przekierowuje strone jesli srodowisko jest dev 
*/ 
function it_is_init_redirect_when_env_is_dev($container,$queryBuilder,$em) 
{ 
    $container->get("doctrine")->willReturn($queryBuilder); 
    $em->createQuery(Argument::any())->willReturn(new Query($em->getWrappedObject())); 
    $this->handleUrl("test"); 
} 

}

+0

Хорошо. Я починил это. Я меняю $ container-> get ("doctrine") => $ container-> get ("doctrine.orm.entity_manager") –

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