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
,因为 AMQPConnection
在 PhpAmqpLib
中被标记为已弃用
您应该添加一种能力来改变正在实例化的 class。
- 添加通过构造函数或 setter 更改连接器 class 的功能,默认情况下使用默认的 AMQPConnector class。使用它来创建连接器对象。 Example
- 为单元测试创建模拟连接器class。 Example
- 使用它通过构造函数或 setter 在测试中设置模拟 class。 Example
您还可以对传递给连接器构造函数的参数进行断言。
另一种方法是使用 amqp interop,这样您就不会耦合到任何实现。当您只处理纯接口时,测试起来要容易得多。
我面临以下问题。我写了一个函数,它在给定所需参数的情况下创建一个连接对象 (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
,因为 AMQPConnection
在 PhpAmqpLib
您应该添加一种能力来改变正在实例化的 class。
- 添加通过构造函数或 setter 更改连接器 class 的功能,默认情况下使用默认的 AMQPConnector class。使用它来创建连接器对象。 Example
- 为单元测试创建模拟连接器class。 Example
- 使用它通过构造函数或 setter 在测试中设置模拟 class。 Example
您还可以对传递给连接器构造函数的参数进行断言。
另一种方法是使用 amqp interop,这样您就不会耦合到任何实现。当您只处理纯接口时,测试起来要容易得多。