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. 「最近」にORDERBYがあります
  2. 制限があります
  3. エンティティには公開日が必要です

Doctrineは異なるバージョン間でSQLを変更できるため、クエリビルダーの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()ただし、この呼び出しは内部で呼び出されることはありません。createQueryBuilderPhpUnitは次のように指摘しています。

FooTest \ Repository \ ArticleRepositoryTest :: testFindRecentLimitsToGivenLimitメソッド名の期待値は、1回呼び出されたときと同じです。メソッドは1回呼び出されると予想されていましたが、実際には0回呼び出されました。

リポジトリモックの作成で何か間違ったことをしたと思います。このアプローチが機能することをどのように確認できますか?または、より良い代替案がある場合、それは何ですか?

4

2 に答える 2

0

It looks to me like you are mocking the Repository you are trying to test, so findRecent() is indeed mocked and will return null.

You should be able to use the real repository instance.

于 2013-03-06T22:22:26.503 に答える