2013-03-06 59 views
3

我有一個自定義實體庫。例如,它看起來像這樣:單元測試定製學說庫

namespace Foo\Repository; 

use Doctrine\ORM\EntityRepository; 

class Article extends EntityRepository 
{ 
    public function findRecent($limit) 
    { 
     $qb = $this->createQueryBuilder('a'); 
     $qb->andWhere('a.publishDate IS NOT NULL') 
      ->orderBy('a.publishDate', 'DESC') 
      ->setMaxResults($limit); 

     return $qb->getQuery()->getResult(); 
    } 
} 

我想在這種情況下進行測試:

  1. 有一個ORDER BY在「近期」
  2. 有一個極限
  3. 實體必須有一個發佈日期

要驗證次的SQL輸出e查詢生成器,因爲Doctrine可以在不同版本之間更改SQL。這將打破我的單元測試。因此,我的想法是這樣的:

  1. 創建我的倉庫
  2. 的模擬創建查詢生成器的模擬
  3. 確保$this->createQueryBuilder('a')返回嘲笑查詢生成器的查詢
  4. 試驗方法調用建設者

在代碼:

namespace FooTest\Repository; 

use PHPUnit_Framework_TestCase as TestCase; 

class ArticleRepositoryTest extends TestCase 
{ 
    protected $qb; 
    protected $repository; 

    public function setUp() 
    { 
     $this->qb   = $this->getMockBuilder('Doctrine\ORM\QueryBuilder') 
           ->disableOriginalConstructor() 
           ->getMock(); 
     $this->repository = $this->getMockBuilder('Foo\Repository\Article') 
           ->disableOriginalConstructor() 
           ->getMock(); 

     $this->repository->expects($this->once()) 
         ->method('createQueryBuilder') 
         ->with($this->equalTo('a')) 
         ->will($this->returnValue($this->qb)); 
    } 

    public function testFindRecentLimitsToGivenLimit() 
    { 
     $limit = '1'; 
     $this->qb->expects($this->any()) 
       ->method('setMaxResults') 
       ->with($this->equalTo($limit)); 

     $this->repository->findRecent($limit); 
    } 

    public function testFindRecentOrdersByPublishDate() 
    { 
     $this->qb->expects($this->any()) 
       ->method('andWhere') 
       ->with($this->equalTo('a.publishDate'), $this->equalTo('DESC')); 

     $this->repository->findRecent(1); 
    } 
} 

findRecent()然而調用從未調用內部createQueryBuilder。 PHPUnit的指出:

FooTest \庫\ ArticleRepositoryTest :: testFindRecentLimitsToGivenLimit 期望失敗方法名稱爲等於當調用1周時間(s)來。方法預計被稱爲1次,實際稱爲0次。

我覺得我做錯了什麼事在創建資源庫模擬。我怎樣才能確保這種方法的工作?或者如果有更好的選擇,那是什麼?

回答

0

它看起來像你對我的嘲笑你想測試庫,所以findRecent()確實是嘲笑和將返回null。

您應該能夠使用真實的版本庫實例。

+1

我嘲笑我自己的對象我的測試,因爲它延伸的學說存儲庫和'createQueryBuilder'不只是簡單地返回一個' QueryBullder對象。我現在已經通過Twitter的幫助,使我的存儲庫部分模擬(工程)。我現在在查詢生成器內部存在鏈接方法的問題,所以不幸的是它不能正常工作:-) – 2013-03-07 08:19:13

0

我發現測試的子類倉庫解決方案是建立模擬當呼叫添加到setMethodsExcept()

所以,你會內setUp()修改代碼上面,像這樣:

$this->repository = $this->getMockBuilder('Foo\Repository\Article') 
    ->disableOriginalConstructor() 
    ->setMethodsExcept([ 
     // Insert any overridden/implemented functions here, in your case: 
     'findRecent', 
    ]) 
    ->getMock();