PHPUnit RabbitMQ:为创建连接函数编写测试

PHPUnit RabbitMQ: write test for create connection function

我面临以下问题。我写了一个函数,它在给定所需参数的情况下创建一个连接对象 (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);
        }
    }
}

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

您是否测试 PDO returns 是否为有效的数据库连接?

如果您测试您的安装而不是测试 php c 库是否正常工作,这可能是有意义的。

@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;
};

N.B.:我在 getConnection() 函数中使用 AMQPStreamConnection,因为 AMQPConnectionPhpAmqpLib

中被标记为已弃用

您应该添加一种能力来改变正在实例化的 class。

  1. 添加通过构造函数或 setter 更改连接器 class 的功能,默认情况下使用默认的 AMQPConnector class。使用它来创建连接器对象。 Example
  2. 为单元测试创​​建模拟连接器class。 Example
  3. 使用它通过构造函数或 setter 在测试中设置模拟 class。 Example

您还可以对传递给连接器构造函数的参数进行断言。

另一种方法是使用 amqp interop,这样您就不会耦合到任何实现。当您只处理纯接口时,测试起来要容易得多。