PHPUnit RabbitMQ: написать тест для создания функции соединения

Я столкнулся со следующей проблемой. Я написал функцию, которая создает объект соединения (AMQPConnection) с заданными параметрами. Теперь я хочу написать соответствующий модульный тест. Я просто не знаю, как это сделать без использования брокера RabbitMQ. Вот эта функция:

public function getConnection($hostKey, array $params) { $connection = null; try { $connection = new AMQPConnection( $params['host'], $params['port'], $params['username'], $params['password'], $params['vhost'] ); // set this server as default for next connection connectionAttempt $this->setDefaultHostConfig($hostKey, $params); return $connection; } catch (\Exception $ex) { if ($this->isAttemptExceeded()) { return $connection; } else { // increment connection connectionAttempt $this->setConnectionAttempt($this->getConnectionAttempt() + 1); return $this->getConnection($hostKey, $params); } } } 

Solutions Collecting From Web of "PHPUnit RabbitMQ: написать тест для создания функции соединения"

Обычно вы не проверяете такой код как Unittest, так как результат скорее скажет вам, что ваш сервер установлен правильно, а не то, что ваш код работает.

Проверяете ли вы, что PDO возвращает действительное соединение с базой данных?

Это может иметь смысл, если вы протестируете свою установку, но не проверяете правильность работы php c lib.

Вы должны добавить возможность изменять создаваемый класс.

  1. Добавьте возможность изменения класса соединителя через конструктор или сеттер со стандартным классом AMQPConnector по умолчанию. Используйте его для создания объекта соединителя. пример
  2. Создайте класс разъединенного класса для модульных тестов. пример
  3. Используйте его, устанавливая класс mock через конструктор или сеттер в тестах. пример

Вы также можете делать утверждения о том, какие аргументы передаются конструктору коннектора.

Другим способом было бы использовать amqp interop, чтобы вы не были связаны с какой-либо реализацией. Намного легче тестировать, поскольку вы имеете дело только с чистыми интерфейсами.

@chozilla @zerkms Итак, благодаря вашим намекам я решил использовать Closure, чтобы изолировать часть кода, подключающуюся к серверу. Вот закрытие:

 $connectionFunction = function ($params) { return new AMQPStreamConnection( $params['host'], $params['port'], $params['username'], $params['password'], $params['vhost'] ); }; 

И здесь изменена функция getConnection()

 /** * @param string $hostKey The array key of the host connection parameter set * @param array $params The connection parameters set * @return null|AMQPStreamConnection */ public function getConnection($hostKey, array $params) { $connection = null; try { $connection = call_user_func($connectionFunction, $params); // set this server as default for next connection connectionAttempt $this->setDefaultHostConfig($hostKey, $params); return $connection; } catch (\Exception $ex) { if ($this->isAttemptExceeded()) { return $connection; } else { // increment connection connectionAttempt $this->setConnectionAttempt($this->getConnectionAttempt() + 1); return $this->getConnection($hostKey, $params); } } } 

Для модульного теста я сделал следующее:

 $mockConnection = $this->getMockBuilder('PhpAmqpLib\Connection\AMQPStreamConnection') ->disableOriginalConstructor() ->getMock(); $connectionFunction = function ($params) use ($mockConnection) { return $mockConnection; }; 

Или у этого есть Исключение.

 $connectionFunction = function ($params) { throw new \Exception; }; 

NB : Я использую AMQPStreamConnection в функции getConnection (), поскольку AMQPConnection отмечен как устаревший в PhpAmqpLib