2014-09-05 2 views
0

Проблема, с которой я столкнулся, заключается в том, что класс mock репозитория возвращает значение null, когда я пытаюсь вызвать методы getSiteFromHost или getAlternateSiteFromHost. Я должен делать что-то неправильно, создавая макет, но я просто не вижу его.Symfony2 Mock Class Returning NULL

Можете ли вы, ребята, найти что-нибудь?

Вот класс (службы), я проверяю:

class SiteHelper { 
    private $container; 
    private $em; 
    private $request; 

    public function __construct($entityManager, $container, $requestStack) { 
     $this->em = $entityManager; 
     $this->container = $container; 
     $this->request = $requestStack->getCurrentRequest(); 
    } 

    public function getCurrentSiteHost() { 
     return $this->request->getHttpHost(); 
    } 

    public function getCurrentSiteObj() {   
     $site = $this->em->getRepository('****') 
       ->getSiteFromHost($this->getCurrentSiteHost()); 

     return $site[0]; 
    } 

    public function getAlternateSiteObj() { 
     $site = $this->em->getRepository('****') 
       ->getAlternateSiteFromHost($this->getCurrentSiteHost()); 

     return $site; 
    } 
} 

А вот тестовый класс:

class SiteHelperTest extends \PHPUnit_Framework_TestCase { 
    private $siteHelper; 

    public function __construct() { 
     $em = $this->buildMockEntityManager(); 
     $container = null; 
     $requestStack = $this->buildMockRequestStack(); 

     $this->siteHelper = new SiteHelper($em, $container, $requestStack); 
    } 

    public function testCurrentSiteHost() 
    { 
     // assert that it's returning what it should be 
     $this->assertEquals($this->siteHelper->getCurrentSiteHost(), '****'); 
    } 

    public function testCurrentSiteObj() 
    {   
     $this->assertEquals($this->siteHelper->getCurrentSiteObj()->getName(), '****'); 
    } 

    public function testAlternateSiteObj() 
    { 
     $this->assertEquals($this->siteHelper->getAlternateSiteObj()->getName(), '****'); 
    } 

    private function buildMockEntityManager() { 
     $site = $this->getMock('\****\Bundle\MainBundle\Entity\Site'); 
     $site->expects($this->once()) 
      ->method('getName') 
      ->will($this->returnValue('****')); 

     $altSite = $this->getMock('\****\Bundle\MainBundle\Entity\Site'); 
     $altSite->expects($this->once()) 
      ->method('getName') 
      ->will($this->returnValue('****')); 

     $siteRepository = $this->getMockBuilder('\Doctrine\ORM\EntityRepository') 
      ->disableOriginalConstructor() 
      ->getMock(); 
     $siteRepository->expects($this->once()) 
      ->method('getSiteFromHost') 
      ->will($this->returnValue(array(0 => $site))); 
     $siteRepository->expects($this->once()) 
      ->method('getAlternateSiteFromHost') 
      ->will($this->returnValue($altSite)); 

     $entityManager = $this->getMockBuilder('\Doctrine\Common\Persistence\ObjectManager') 
      ->disableOriginalConstructor() 
      ->getMock(); 
     $entityManager->expects($this->once()) 
      ->method('getRepository') 
      ->will($this->returnValue($siteRepository)); 

     return $entityManager; 
    } 

    private function buildMockRequestStack() { 
     $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request') 
      ->disableOriginalConstructor() 
      ->getMock(); 
     $request->expects($this->once()) 
      ->method('getHttpHost') 
      ->will($this->returnValue('medicare.localhost')); 

     $requestStack = $this->getMockBuilder('\Symfony\Component\HttpFoundation\RequestStack') 
      ->disableOriginalConstructor() 
      ->getMock(); 
     $requestStack->expects($this->once()) 
      ->method('getCurrentRequest') 
      ->will($this->returnValue($request)); 

     return $requestStack; 
    } 
} 
+0

возможно '' '$ entityManager-> expects ($ this-> once())' '' должно быть: '' '$ entityManager-> expects ($ this-> any())' ''? – skler

+0

Нет, это все равно дает ту же ошибку. Спасибо за предложение. Какое значение имеет один раз против любого? – xil3

+0

Не обращайте внимания на один раз против любого - понял это. – xil3

ответ

1

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

class TmpTest extends \PHPUnit_Framework_TestCase 
{ 
    private $em; 

    public function __construct() 
    { 
     $this->em = $this->buildMockEntityManager(); 
    } 

    public function testCurrentSiteHost() 
    { 
     $this->assertEquals("pippo", 
      $this->em->getRepository('\ACME\YourBundle\Entity\MyBetterCodedEntity')->getSiteFromHost() 
     ); 
     $this->assertEquals(
     [0 => "pluto"], 
      $this->em->getRepository('\ACME\YourBundle\Entity\MyBetterCodedEntity')->getAlternateSiteFromHost() 
     ); 
    } 

    private function buildMockEntityManager() 
    { 

     // Main bug was here, you have to mock the Class with the real methods, not the parent that doesn't has getSiteFromHost method (so it can't be mocked) 
     $siteRepository = $this->getMockBuilder('\ACME\YourBundle\Repository\MyBetterCodedEntityRepository') 
      ->disableOriginalConstructor() 
      ->getMock(); 

     $siteRepository->expects($this->once()) 
      ->method('getSiteFromHost') 
      ->will($this->returnValue("pippo")); 

     $siteRepository->expects($this->once()) 
      ->method('getAlternateSiteFromHost') 
      ->will($this->returnValue([0 => "pluto"])); 

     $entityManager = $this->getMockBuilder('\Doctrine\Common\Persistence\ObjectManager') 
      ->disableOriginalConstructor() 
      ->getMock(); 

     // Exactly means that this will be called "2" times otherwise is an error. 
     $entityManager->expects($this->exactly(2)) 
      ->method('getRepository') 
      // you can define here the expected parameter 
      //->with('\ACME\YourBundle\Entity\MyBetterCodedEntity') 
      ->will($this->returnValue($siteRepository)); 

     return $entityManager; 
    } 

} 

хорошо, это тест тест :)