For each test case is better to load less fixture as possible both for isolation and for performance (the test suite can go very slowly).
When fixture depends each other, you simply manage them with the doctrine reference and link each other, take care of the order also.
As Example, suppose the simply user and role relations.
A generic class for manage role fixture:
abstract class BaseLoadRoleData extends AbstractFixture implements OrderedFixtureInterface
{
public function getOrder()
{
return 1;
}
protected function createRole(ObjectManager $manager, $rolename)
{
$role= new Role();
$role->setName($rolename);
$manager->persist($role);
$manager->flush();
$this->setReference('role-' . $rolename, $role);
}
}
A Dedicated class for the Simple Role
class LoadSimpleRoleData extends BaseLoadRoleData
{
public function load(ObjectManager $manager)
{
$this->createRole($manager, Role::SIMPLE);
}
}
A Dedicated class for the Admin Role
class LoadAdminRoleData extends BaseLoadRoleData
{
public function load(ObjectManager $manager)
{
$this->createRole($manager, Role::ADMIN);
}
}
And the user:
A generic class for manage user fixture:
abstract class BaseLoadUserData extends AbstractFixture implements OrderedFixtureInterface
{
/**
* @var ContainerInterface
*/
private $container;
/**
* {@inheritDoc}
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
public function getOrder()
{
return 2;
}
protected function buildUser($username, $firstName = "",$lastName ="")
{
$user= new User();
$user->setUsername($username);
$user->setFirstName($firstName);
$user->setLastName($lastName);
return $user;
}
}
A Dedicated class for the Simple User
class LoadSimpleUserData extends BaseLoadUserData {
/**
* Load data fixtures with the passed EntityManager
*
* @param Doctrine\Common\Persistence\ObjectManager $manager
*/
function load(ObjectManager $manager)
{
$user = $this->buildUser($manager, "[email protected]");
$user->addRole($this->getReference('role-'.Role::SIMPLE));
$manager->persist($user);
$manager->flush();
$this->setReference('user-' . "[email protected]", $user);
}
}
A Dedicated class for the Admin User
class LoadAdminUserData extends BaseLoadUserData {
/**
* Load data fixtures with the passed EntityManager
*
* @param Doctrine\Common\Persistence\ObjectManager $manager
*/
function load(ObjectManager $manager)
{
$user = $this->buildUser($manager, "[email protected]");
$user->addRole($this->getReference('role-'.Role::ADMIN));
$manager->persist($user);
$manager->flush();
$this->setReference('user-' . "[email protected]", $user);
}
Now you can use it separately, as example, based on the Liip Functional Test Bundle:
class LoginControllerTest {
public function testAdminUserLogin()
{
$this->loadFixtures(array(
'Acme\DemoBundle\DataFixtures\ORM\LoadAdminRoleData',
'Acme\DemoBundle\DataFixtures\ORM\LoadAdminUserData'
));
// you can now run your functional tests with a populated database
$client = static::createClient();
// ...
// test the login with admin credential
}
public function testSimpleUserLogin()
{
// add all your fixtures classes that implement
// Doctrine\Common\DataFixtures\FixtureInterface
$this->loadFixtures(array(
'Acme\DemoBundle\DataFixtures\ORM\LoadSimpleRoleData',
'Acme\DemoBundle\DataFixtures\ORM\LoadSimpleUserData'
));
// you can now run your functional tests with a populated database
$client = static::createClient();
// ...
// test the login with simple user credential
}
}
Hope this help.