Как уловить 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));
    }
}

См. документация для получения дополнительных методов.