Исключение не обрабатывается правильным методом с использованием PhpUnit

Я пытаюсь создать библиотеку для личного проекта с использованием сокетов php. Для этого я начал использовать phpUnit, чтобы изучить и написать (более или менее) качественную библиотеку.

Когда я не предоставляю блок try/catch в методе testConnection, php выдает ошибку, что время ожидания соединения истекло (что нормально, потому что устройство не подключено). Но php должен обрабатывать исключение в методе execute ниже, а не в методе testConnection. И я не могу понять это.

Это ошибка:

PHPUnit_Framework_Error_Warning : stream_socket_client(): unable to connect to tcp://x.x.x.x:* (A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.)

Testclass с методом и try/catch, которых там быть не должно:

public function testConnection() {
    $adu = new Adu();
    $adu->setPort('AS0');
    $adu->setData('?');

    $command = new Command('x.x.x.x', *);
    $command->setAduSent($adu);

    try
    {
        $command->execute();
    }
    catch (Exception $e)
    {
        echo $e->getMessage();
    }
}

Это (метод выполнения) - это то место, где должно обрабатываться исключение:

public function execute()
{
    try {
        $this->stream = $this->createStream($this->address, $this->port, $this->timeout);
    }
    catch(Exception $e) {
        $this->logger->error('Exception (' . $e->getCode() . '): ' . $e->getMessage() . ' on line ' . $e->getLine(), $e);
    }

    $this->send($this->stream, $this->aduSent);
    $this->aduReceived = $this->receive($this->stream);
}

private function createStream($address, $port, $timeout = 2)
{
    $stream = stream_socket_client('tcp://' . $address . ':' . $port, $errorCode, $errorMessage, $timeout);

    if(!$stream) {
        throw new Exception('Failed to connect(' . $errorCode . '): ' . $errorMessage);
    }

    return $stream;
}

Решение

Поскольку try/catch не будет обнаруживать ошибки/предупреждения, мне пришлось подавить предупреждения, вызванные stream_socket_client. Затем проверьте, является ли возвращаемое значение ложным или потоковым объектом. Если false, сгенерируйте соответствующее исключение.

$stream = @stream_socket_client('tcp://' . $address . ':' . $port, $errorCode, $errorMessage, $timeout);

person glenz0r    schedule 18.05.2014    source источник


Ответы (1)


Предложение stream_socket_client выдает предупреждение, а не исключение, и предупреждения не перехватываются блоками try/catch.

Но PHPUnit перехватывает предупреждения и в этом случае генерирует исключение, поэтому возникает ошибка. Вы можете настроить PHPUnit, чтобы он не считал предупреждения ошибками, хотя я бы не рекомендовал этого делать. Ваш код не должен содержать предупреждений. Документация по PHPUnit.

person gontrollez    schedule 19.05.2014
comment
Спасибо за информацию! Но как я могу избежать предупреждения? Потому что нужно иметь в виду, что соединение не может быть установлено. Если я не использую stream_socket_client и не пишу сокет с нуля. И проверить, есть ли таймаут, а потом кинуть исключение самому, если это возможно. - person glenz0r; 20.05.2014