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();
}
Надеюсь, что это поможет кому-то.