Подигравка на Propel Query във функция (Symfony2)

Опитвам се да напиша единичен тест (използвайки phpunit и mockery) за клас, който използва Propel заявка.
Как да се подигравам на заявката $contact = ClientContactQuery::create()->findPK($id);

Мъча се да намеря примери за това.

Моят клас;

<?php
namespace MyBundle\Classes;

use MyBundle\Model\ClientContactQuery;
use MyBundle\Model\ClientContact;

class Contacts {

    protected $_cache;

    public function __construct($cache)
    {
        $this->_cache = $cache;
    }

    public function getContact($id)
    {
        $contact = ClientContactQuery::create()->findPK($id);

        if (! $contact) {
            throw new NotFoundHttpException('Client contact not found.');
        }

        return $contact;
    }

}

Моят тестов случай досега;

<?php
namespace MyBundle\Tests\Classes;

use Mockery as m;
use MyBundle\Classes\Contacts as c;

class ContactsTest extends \PHPUnit_Framework_TestCase
{
    public function tearDown()
    {
        m::close();
    }

    public function testGetValidContact()
    {
        // Arrange
        $cache = m::mock('cache');

        // Act
        $contact = new c($cache);
        // am lost at this point :-(

        // Assert
        $this->assertInstanceOf('MyBundle\Classes\Contacts', $contact);
    }

}

person Rooneyl    schedule 23.01.2014    source източник


Отговори (2)


Статичните функции не работят добре с тестването на единици и моля, не създавайте частен метод и не му се подигравайте.

Горещо препоръчвам да създадете Query Factory. Това не само ще ви даде възможност да инжектирате и тествате модула на вашия код, но ще улесни живота ви, ако искате да използвате XYZ orm вместо Propel в бъдеще.

#

<?php
namespace MyBundle\Classes;

use MyBundle\Model\ClientContactQuery;
use MyBundle\Model\ClientContact;

class Contacts {

    protected $_cache;

    /** @var QueryFactory */
    private $queryFactory;


    public function __construct( $cache, QueryFactory $queryFactory ) {
        $this->_cache = $cache;
        $this->queryFactory = $queryFactory;
    }

    public function getContact( $id ) {
        $contact = $this->queryFactory->newClientContactQuery()->findPK($id);

        if (! $contact) {
            throw new NotFoundHttpException('Client contact not found.');
        }

        return $contact;
    }

}

#

<?php
class QueryFactory {

    const CLASS_NAME = __CLASS__;

    public function newClientContactQuery() {
        return ClientContactQuery::create();
    }

    public function newSomeOtherQuery() {
        return SomeOtherQuery::create();
    }

}

#

<?php
namespace MyBundle\Tests\Classes;

use Mockery as m;
use MyBundle\Classes\Contacts as c;

class ContactsTest extends \PHPUnit_Framework_TestCase {
    public function tearDown() {
        m::close();
    }

    public function testGetValidContact() {
        $cache              = m::mock( 'cache' );
        $queryFactory       = m::mock( QueryFactory::CLASS_NAME );
        $clientContactQuery = m::mock( 'ClientContanctQuery' );

        $contact = new c($cache, $queryFactory);

        $queryFactory->shouldReceive('newClientContactQuery')->with()->once()->andReturn( $clientContactQuery );
        $clientContactQuery->shouldReceive('findPK')->with('myTestInputId')->once->andReturn('something?');

        $this->assertInstanceOf('MyBundle\Classes\Contacts', $contact);
    }

}
person kali    schedule 31.01.2014

Наистина не можете да му се подигравате, защото имате „твърда“ зависимост от него. Така че, за да разрешите този проблем, трябва да помислите за преместване на „твърда“ зависимост от заявка от метода getContact.

Можете да го направите по три начина:

  1. Създайте свой частен метод, напр. ж. "getQueryFindByPk", и след това го подигравайте във вашия клас Контакти, за да върнете това, от което се нуждаете.
  2. Предайте екземпляр на заявка към конструктор, но доколкото разбирам, можете да имате множество екземпляри на заявка.
  3. Създайте нещо като QueryFactory, Repository или QueryBuilder, което може да ви върне екземпляр на заявка.

И така, отново проблемът е в наличието на "твърда" зависимост от заявка.

person Dmytro Krasun    schedule 31.01.2014