2016-01-21 152 views
2

我已经给自己一个挑战,就是在开发它时使用测试我的代码,因为我认为这不仅是一个很好的做法,特别是对于后端开发人员,而且还有助于构建从长远来看可扩展和可扩展的代码。PHPUnit和域例外测试

我有一个类,它定义了支持的教义驱动程序的数组。在这个类里面有一个方法可以创建我的包支持的任何注解驱动程序的实例。

protected $supportedAnnotationDrivers = array(
    'Doctrine\ORM\Mapping\Driver\XmlDriver', 
    'Doctrine\ORM\Mapping\Driver\YamlDriver', 
    'Doctrine\ORM\Mapping\Driver\AnnotationDriver' 
); 

创建这些驱动程序的任何实例的方法可以在下面看到:

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; 
    } 

之前,我去任何进一步的我不得不说,我已经咨询PHPUnit的手册和StackOverflow上,here; here; herethere,对于一些见解,但我总是感到困惑。而且这些链接都没有提供给我确切的信息,即我正在以正确的方式进行。

下面是我的测试类在我的测试功能:

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!.'); 
    } 

我真的很困惑,当涉及到这部分。在我的测试中,我正在使用由RuntimeException和我的测试通过的代码引发的异常。当我更改客户端代码以引发异常,但将我的测试保持原样时,它将失败并从客户端代码抛出异常。我很高兴知道我的测试失败了,因为我的测试中抛出的异常给了我当用户传递不受支持的驱动程序时希望得到的结果。

不过,我缺乏语境这里的注解的使用和测试异常时,$这个 - >不合格(“文/为/ failer /)功能。

我如何能最好去写一个测试这种方法?我所做的究竟是测试应该如何表现或许我没有把握这部分PHPUnit背后的概念?下面是我从PHPUnit得到的输出:

情况1:例外情况与测试相同和客户代码

[email protected] 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) 

[email protected] MINGW64 /d/web/doctrine-bundle 

情况2:异常是不能从测试和客户端代码相同

[email protected] 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 

例外:学说\ ORM \映射\驱动\ StaticPHPDriver是不受支持的注释驱动程序。

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. 

我真的很想知道知道我在这里做的最好办法,如果我这样做是正确的 - 如果不这样做的最佳方式。 Perpahs我试图做的事情甚至都没有做到,但我相信没有一行代码应该被视为毫无价值和不值得的测试。

回答

2

一般而言,您提供的代码是有效的,并且应该按其应有的方式工作。您描述了您期望的代码,然后测试您的代码是否符合您的期望。

在你的情况,你期待与\RuntimeException类型将引发异常,如果它只是\Exception - 有错误

的另一个问题是如何PHPUnit的事告诉你。在你的情况它显示消息

1) PhpUnitBundle\Unit\ApplicationContext\Service\EntityManagerServiceTest::testUnsupportedAnnotationDriverException 
Exception: Doctrine\ORM\Mapping\Driver\StaticPHPDriver is not a supported Annotation Driver. 

这是不是很明显。 您可以预期更明确,如果有setExpectedException descibe他们:用适当的注释@expectedException

/** 
* Test fail if client requests a unsupported driver 
*/ 
public function testUnsupportedAnnotationDriverException() 
{ 
    $entityManagerService = new EntityManagerService(); 

    $this->setExpectedException(\RuntimeException::class); 
    // $this->setExpectedException('RuntimeException'); // for PHP < 5.5 

    $unsupportedDriver = 'Doctrine\ORM\Mapping\Driver\StaticPHPDriver'; 
    $actualUnsupportedException = $entityManagerService->getAnnotationDriver(
     $unsupportedDriver, __DIR__ . '/../../Helper' 
    ); 
} 

或:

/** 
* Test fail if client requests a unsupported driver 
* 
* @expectedException \RuntimeException 
*/ 
public function testUnsupportedAnnotationDriverException() 
{ 
    $entityManagerService = new EntityManagerService(); 

    $unsupportedDriver = 'Doctrine\ORM\Mapping\Driver\StaticPHPDriver'; 
    $actualUnsupportedException = $entityManagerService->getAnnotationDriver(
     $unsupportedDriver, __DIR__ . '/../../Helper' 
    ); 
} 

现在,如果你在测试方法改变throw \RuntimeExceptionthrow \Exception,你可以注意到,PHPUnit的消息现在看起来像这样

Failed asserting that exception of type "Exception" matches expected exception "\RuntimeException". Message was: "Doctrine\ORM\Mapping\Driver\StaticPHPDriver is not a supported Annotation Driver." 

所以哟你看更明确什么是错的

+0

谢谢@SmoothAF。我会再试一次,如果我满意,我会回来接受你的回答。感谢你的宝贵时间。 – Maximum86