PHPUnit RabbitMQ:为create connection函数编写测试

时间:2015-05-20 08:11:20

标签: php 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);
        }
    }
}

3 个答案:

答案 0 :(得分:4)

您通常不会将此类代码作为Unittest进行测试,因为结果更可能会告诉您服务器安装正确而不是您的代码正在运行。

您是否测试PDO是否返回有效的数据库连接?

如果你测试你的安装但是不测试php c libs是否正常工作可能是有意义的。

答案 1 :(得分:0)

您应该添加更改正在实例化的类的功能。

  1. 添加通过构造函数或setter更改连接器类的功能,默认情况下使用默认的AMQPConnector类。使用它来创建连接器对象。 Example
  2. 为单元测试创​​建一个模拟的连接器类。 Example
  3. 使用它在测试中通过构造函数或setter设置mock类。 Example
  4. 您还可以对传递给连接器构造函数的参数进行断言。

    另一种方法是使用amqp interop,这样就不会与任何实现相结合。在处理纯接口时,更容易进行测试。

答案 2 :(得分:-1)

@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 :我在 getConnection()函数中使用AMQPStreamConnection,因为AMQPConnectionPhpAmqpLib中被标记为已弃用