Как уловить PHP-предупреждение в PHPUnit
Я пишу тестовые примеры, и вот вопрос, который у меня есть.
Так сказать, я тестирую простую функцию someClass::loadValue($value)
Обычный тестовый пример прост, но при передаче в нуле или -1 вызов функции генерирует предупреждение PHP, которое считается ошибкой.
Вопрос в том, как написать свой тестовый пример PHPUnit, чтобы он успел, когда функции обрабатывают нуль /-1 изящно и не работают, когда появляется предупреждение PHP?
Спасибо,
Ответы
Ответ 1
PHPUnit_Util_ErrorHandler::handleError()
выдает один из нескольких типов исключений на основе кода ошибки:
-
PHPUnit_Framework_Error_Notice
для E_NOTICE
, E_USER_NOTICE
и E_STRICT
-
PHPUnit_Framework_Error_Warning
для E_WARNING
и E_USER_WARNING
-
PHPUnit_Framework_Error
для всех остальных
Вы можете поймать и ожидать их, как и любое другое исключение.
/**
* @expectedException PHPUnit_Framework_Error_Warning
*/
function testNegativeNumberTriggersWarning() {
$fixture = new someClass;
$fixture->loadValue(-1);
}
Ответ 2
Я бы создал отдельный случай для проверки, когда ожидается уведомление/предупреждение.
Для PHPUnit v6.0 + это обновленный синтаксис:
use PHPUnit\Framework\Error\Notice;
use PHPUnit\Framework\Error\Warning;
use PHPUnit\Framework\TestCase;
class YourShinyNoticeTest extends TestCase
{
public function test_it_emits_a_warning()
{
$this->expectException(Warning::class);
file_get_contents('/nonexistent_file'); // This will emit a PHP Warning, so test passes
}
public function test_it_emits_a_notice()
{
$this->expectException(Notice::class);
$now = new \DateTime();
$now->whatever; // Notice gets emitted here, so the test will pass
}
}
Ответ 3
Для меня работала модификация моего phpunit.xml, чтобы
<phpunit
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
strict="true"
>
</phpunit>
Ключ должен был использовать strict="true"
, чтобы получить предупреждения в результате неудавшегося теста.
Ответ 4
Вы также можете написать файл phpunit.xml(в диалоговом окне тестов):
<phpunit
convertErrorsToExceptions="true"
convertNoticesToExceptions="false"
stopOnFailure="false">
</phpunit>
Ответ 5
Используя Netsilik/BaseTestCase (лицензия MIT), вы можете напрямую проверять наличие инициированных ошибок/предупреждений, не преобразовывая их в исключения:
composer require netsilik/base-test-case
Тестирование для E_USER_NOTICE
:
<?php
namespace Tests;
class MyTestCase extends \Netsilik\Testing\BaseTestCase
{
/**
* {@inheritDoc}
*/
public function __construct($name = null, array $data = [], $dataName = '')
{
parent::__construct($name, $data, $dataName);
$this->_convertNoticesToExceptions = false;
$this->_convertWarningsToExceptions = false;
$this->_convertErrorsToExceptions = true;
}
public function test_whenNoticeTriggered_weCanTestForIt()
{
$foo = new Foo();
$foo->bar();
self::assertErrorTriggered(E_USER_NOTICE, 'The warning string');
}
}
Надеюсь, это поможет кому-то в будущем.
Ответ 6
Сделать SomeClass выдать ошибку, если ввод недействителен, и сообщить phpUnit о ожидаемой ошибке.
Один из способов:
class ExceptionTest extends PHPUnit_Framework_TestCase
{
public function testLoadValueWithNull()
{
$o = new SomeClass();
$this->setExpectedException('InvalidArgumentException');
$this->assertInstanceOf('InvalidArgumentException', $o::loadValue(null));
}
}
См. документация для получения дополнительных методов.