I have given myself a challenge to making use of testing my code as I develop it as I figured this is not only a good practice especially for a back end developer but also helps one a lot in building a scalable and extendable code in the long run.
I have a class that defines an array of supported doctrine drivers. Inside this class there is a method that creates an instance of any annotation driver that is supported by my bundle.
protected $supportedAnnotationDrivers = array(
'Doctrine\ORM\Mapping\Driver\XmlDriver',
'Doctrine\ORM\Mapping\Driver\YamlDriver',
'Doctrine\ORM\Mapping\Driver\AnnotationDriver'
);
The method that creates any instance of these drivers can be seen below:
public function getAnnotationDriver($classDriver, $entityDriver)
{
if(!in_array($classDriver, $this->supportedAnnotationDrivers)){
throw new \RuntimeException(sprintf(
"%s is not a supported Annotation Driver.", $classDriver
));
}
if('Doctrine\ORM\Mapping\Driver\AnnotationDriver' === $classDriver){
$annotationDriver = new $classDriver(new AnnotationReader(), array($entityDriver));
AnnotationRegistry::registerLoader('class_exists');
}else{
$annotationDriver = new $classDriver($entityDriver);
}
return $annotationDriver;
}
Before I go any further I have to say I have consulted PHPUnit Manual and StackOverflow, here; here; here and there , for some insights but I am getting confused all the time. and none of these links are providing me with certainty that I am going about this the right way.
Below is my test function inside my test class:
public function testUnsupportedAnnotationDriverException()
{
try{
$entityManagerService = new EntityManagerService();
//Client requests a unsupported driver
$unsupportedDriver = 'Doctrine\ORM\Mapping\Driver\StaticPHPDriver';
$actualUnsupportedException = $entityManagerService->getAnnotationDriver(
$unsupportedDriver, __DIR__ . '/../../Helper'
);
}catch(\RuntimeException $actualUnsupportedException){
return;
}
$this->fail('An expected exception has not been raised!.');
}
I am really confused when it comes to this part. In my test I am using an exception that is raised by my code which is RuntimeException and my test passes. When I change client code to throw just Exception but leave my test as is it fails and throws the exception from client code. I am happy to know that my test fails because the exception thrown in my test gives me what I would hope to get when a user passes an unsupported driver.
However, I am lacking contextualization herein of the annotation usage and the $this->fail("text/for/failer/) function when testing exceptions.
How best could I go about writing a test for this method? Is what I have done exactly how the test should behave perhaps its me not having grasp the concept behind this part of PHPUnit? Below is an output I get from PHPUnit:
Case 1:Exceptions are the same from test and client code
Luyanda.Siko@ZACT-PC301 MINGW64 /d/web/doctrine-bundle
$ vendor/bin/phpunit
PHPUnit 3.7.38 by Sebastian Bergmann.
Configuration read from D:\web\doctrine-bundle\phpunit.xml
......
Time: 1.49 seconds, Memory: 3.00Mb
OK (6 tests, 9 assertions)
Luyanda.Siko@ZACT-PC301 MINGW64 /d/web/doctrine-bundle
Case 2:Exceptions are not the same from test and client code
Luyanda.Siko@ZACT-PC301 MINGW64 /d/web/doctrine-bundle
$ vendor/bin/phpunit
PHPUnit 3.7.38 by Sebastian Bergmann.
Configuration read from D:\web\doctrine-bundle\phpunit.xml
..E...
Time: 1.59 seconds, Memory: 3.00Mb
There was 1 error:
1) PhpUnitBundle\Unit\ApplicationContext\Service\EntityManagerServiceTest::testUnsupportedAnnotationDriverException
Exception: Doctrine\ORM\Mapping\Driver\StaticPHPDriver is not a supported Annotation Driver.
D:\web\doctrine-bundle\lib\DoctrineBundle\ApplicationContext\Service\EntityManagerService.php:33
D:\web\doctrine-bundle\lib\PhpUnitBundle\Unit\ApplicationContext\Service\EntityManagerServiceTest.php:68
FAILURES!
Tests: 6, Assertions: 9, Errors: 1.
I really want to know the best way to know what I am doing here and if I am doing it right - if not the best way to do it. Perpahs what I am trying to do is not even worthe it but I believe no single line of code should be seen as worthless and unworthy of testing.