Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jessegreathouse/1015828 to your computer and use it in GitHub Desktop.
Save jessegreathouse/1015828 to your computer and use it in GitHub Desktop.
#Heres a quick mock up of an idea to use fixtures in a non-symfony way to aid in unit testing. The Unit testing fixtures wont get mixed up with application oriented fixtures.
<?php
#Tests/Service/CustomerPurchaseControlTest.php
namespace CodeMeme\CommerceBundle\Tests\Service;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use CodeMeme\CommerceBundle\Tests\Fixtures\Job\LoadJobQueueControlTestData;
use CodeMeme\CommerceBundle\Model\Cart\ActiveCart;
use CodeMeme\CommerceBundle\Entity\Purchase;
class CustomerPurchaseControlTest extends WebTestCase
{
protected $data = array();
protected $kernel;
//You could put this data in the actual fixture but I think its much more convenient to keep it in the actual test and just load it into the fixture on-demand. For maintaining the code it just makes it easier if the unit tests are more self contained.
public static function purchaseProvider()
{
return
array(
'activePurchases' => array(
array(
'executable' => 'console purchase:test1',
'type' => 'Goods',
'active' => 1,
),
array(
'executable' => 'console purchase:test2',
'type' => 'Services',
'active' => 1,
),
array(
'executable' => 'console purchase:test3',
'type' => 'Credits',
'active' => 1,
),
array(
'executable' => 'console purchase:test4',
'type' => 'Rebate',
'active' => 1,
),
),
);
}
public function setUp()
{
$this->kernel = $this->createKernel(array('environment' => 'test'));
$this->kernel->boot();
$this->container = $this->kernel->getContainer();
}
public function tearDown()
{
unset($this->container);
}
/**
* @dataProvider purchaseProvider
*/
public function testRunActiveCart($p1, $p2, $p3, $p4)
{
//loads up the fixtures
$em = $this->container->get('doctrine')->getEntityManager();
$activeCart = array($p1, $p2, $p3, $p4);
$fixtures = new LoadPurchaseControlTestData($this->kernel);
$fixtures->setData($activeCart);
$this->data = $fixtures->load($em);
// Once the fixtures are loaded you can test your data
$this->container->get('cart.control')->checkout();
$result = array();
$repo = $em->getRepository('CommerceBundle:Purchase');
foreach ($this->data as $record) {
array_push($result, $repo->findOneById($record->getId())->getStatus());
}
$this->assertTrue((count(array_keys($result, 'success')) === 4), "");
}
}
<?php
#Tests/Fixtures/Purchase/LoadPurchaseControlTestData.php
namespace CodeMeme\CommerceBundle\Tests\Fixtures\Purchase;
use CodeMeme\CommerceBundle\Tests\Fixtures\Job\LoadPurchaseTestData;
class LoadPurchaseControlTestData extends LoadPurchaseTestData
{
//The final class has a 1 to 1 relationship with the unit test. Only the unit test with the same name will use this fixture.
//all data customizations go here.
//this ones needs the kernel to do some data treatment
//some test cases wont need any data treatment but this layer is there in case they do
private $_kernel;
public function __construct(HttpKernelInterface $kernel)
{
$this->kernel = $kernel;
}
public function setData($data)
{
foreach ($data as &$record) {
$record['executable'] = $this->kernel->getRootDir() . '/app/' . $record['executable'];
}
$this->data = $data;
}
}
<?php
#Tests/Fixtures/Purchase/LoadPurchaseTestData.php
namespace CodeMeme\CommerceBundle\Tests\Fixtures\Purchase;
use CodeMeme\CommerceBundle\Entity\Purchase;
use CodeMeme\CommerceBundle\Tests\Fixtures\LoadTestData;
//The second layer of abstraction tailors the fixture on the ORM level
abstract class LoadPurchaseTestData extends LoadTestData
{
public function load($manager)
{
$result = array();
foreach ($this->data as $record) {
$testPurchase = new Job;
$testPurchase->setCreateDate(new \DateTime);
foreach ($record as $key => $val) {
$testPurchase->{'set'.ucwords($key)}($val);
}
$manager->persist($testPurchase);
array_push($result, $testPurchase);
$manager->flush();
unset($testPurchase);
}
return $result;
}
}
<?php
#Tests/Fixtures/LoadTestData.php
namespace CodeMeme\CommerceBundle\Tests\Fixtures;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;
//two layers of abstraction, the first layer simply abstracts all fixtures
abstract class LoadTestData implements FixtureInterface
{
protected $data = array();
public function setData($data)
{
$this->data = $data;
}
public function getData()
{
return $this->data;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment