PHPUnit не может найти класс исключения

Я использую namespacing в 5.3 и пытаюсь проверить ожидаемое исключение в PHPUnit с картой Symfony2.

Я ожидаю, что будет выбрано исключение, и когда я использую

$this->setExpectedException('ImageResizerException');

Я получаю следующую ошибку:

PHPUnit 3.7.13 Себастьяна Бергмана.

Конфигурация, прочитанная из /var/www/branches/ 3.6.0/api/app/phpunit.xml.dist

.E.................

Время: 1 секунда, Память: 18.25Mb

Произошла 1 ошибка:

1) AssetManagerBundle\Tests\Services\ImageResizerTest:: testOriginalFile ReflectionException: Class ImageResizerException не существует

FAILURES! Тесты: 19, Утверждения: 54, Ошибки: 1.

У меня есть следующая структура:

  • AssetManagerBundle\Services\ImageResizer.php
  • AssetManagerBundle\Services\Исключения\ImageResizerException.php
  • AssetManagerBundle\Тесты\Services\ImageResizerTest.php

Мой тестовый класс:

<?php
    namespace AssetManagerBundle\Tests\Services;

    use AssetManagerBundle\Services\ImageResizer;
    use AssetManagerBundle\Services\Exceptions\ImageResizerException;

class ImageResizerTest extends \PHPUnit_Framework_TestCase
{

    public function testOriginalFile()
    {
        $ir = new ImageResizer();
        // test default value
        $this->assertEquals('', $ir->getOriginalFile());

        // test invalid filename
        $this->setExpectedException('ImageResizerException');
        $ir->setOriginalFile('/tmp/test.file');
        $this->assertEquals('/tmp/test.file', $ir->getOriginalFile());


        // test valid filename
        $temp_name  = tempnam(sys_get_temp_dir(), 'test_'.time());
        $handle     = fopen($temp_name, 'w+');
        fwrite($handle, ' ');
        fclose($handle);

        $ir->setOriginalFile($temp_name);
        $this->assertEquals($temp_name, $ir->getOriginalFile());
    }
    // more code....
}

Нужно ли мне что-то делать для PHPUnit, чтобы увидеть мой класс исключений?

Версия PHP:

PHP 5.3.10-1ubuntu3.5 с Suhosin-Patch (cli) (построено: 18 января 2013 г. 23:45:59) Copyright (c) 1997-2012 PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies     с Xdebug v2.1.0, Copyright (c) 2002-2010, Derick Rethans

Ответ 1

Вам необходимо полностью квалифицировать класс исключений вместе с его пространством имен. Для примера:

$this->setExpectedException('\AssetManagerBundle\Services\Exceptions\ImageResizerException');

или

use AssetManagerBundle\Services\Exceptions\ImageResizerException;
$exceptionClass = get_class(new ImageResizerException(''));
$this->setExpectedException($exceptionClass);

Ответ 2

Вам нужно использовать FQCN исключения ImageResizerException:

AssetManagerBundle\Services\Exceptions\ImageResizerException

Предложение use в верхней части файла предназначено только для этого файла - не для PHPUnit, который имеет код в некоторых других файлах.

Исправление: это не (только), что предложение use не работает для PHPUnit, но поскольку ReflectionClass ожидает FQCN. Это похоже на использование переменной (динамического) класса-имени в PHP, например new $var:

<?php

namespace Sugar {
    class Exception extends \Exception {}
}
namespace {
    use Sugar\Exception;

    $class = 'Sugar\Exception';
    $e = new $class;
    var_dump($e);
}

Вывод:

object(Sugar\Exception)#1 (7) {
  ["message":protected]=>
  string(0) ""
  ["string":"Exception":private]=>
  string(0) ""
  ["code":protected]=>
  int(0)
  ["file":protected]=>
  string(45) "/tmp/execpad-7141d0116de7/source-7141d0116de7"
  ["line":protected]=>
  int(10)
  ["trace":"Exception":private]=>
  array(0) {
  }
  ["previous":"Exception":private]=>
  NULL
}

Демо: http://eval.in/7883

Ответ 3

Вместо того, чтобы писать имя класса, вместо этого используйте полное пространство имен класса. Тогда вы не получите исключение "класс не существует".

Ответ 4

    $this->setExpectedException(ImageResizerException::class);

- это способ сделать это, используя импортированное пространство имен из инструкции use

Ответ 5

У меня была аналогичная проблема, но с phpunit, объявляя @expectedException, он также нуждался в FQCN.

 /**
 * @expectedException \PHPNS\Core\MyCustomException
 */
public function testIfListIsEmpty()
{
    $fab = new PHPList();                         
}

Надеюсь, что это поможет кому-то.