gpt4 book ai didi

php - 我不知道如何用 PHPUnit 测试 Ratchet/Sockets

转载 作者:行者123 更新时间:2023-12-04 15:14:24 25 4
gpt4 key购买 nike

首先让我承认,我在 TDD 和单元测试领域绝对是一个新手。目前,我正在学习使用 TDD 来提升自己的职业生涯。

我正在重新编写一年前使用 TDD 编写的程序。该程序并不那么复杂。它监听一个 websocket (Ratchet),接收信息,解析信息,并通过消息总线 (RabbitMQ) 发送消息。

我正尝试通过 TDD 来解决这个问题,所以我开始先编写我的测试。

我的监听器类有 4 个方法。

  • Connect(通过 Ratchet 连接到流)
  • Listen(开始听)
  • Parse(解析接收到的信息)
  • SendMessage(向 RabbitMQ 总线发送消息)

先写测试遇到的问题。

  • 如何模拟 Ratchet 连接并断言我的函数可以“连接”
  • 我如何断言收到的信息符合我的预期

我发现很难找到关于这个特定主题的信息,而且我知道我的问题很宽泛。我不期望有完整的解决方案或答案,但希望有进一步研究该主题的术语以及有关为此类方法编写测试的讲座/教程。

最佳答案

没有看过任何代码就很难争论。根据您的描述,听起来您有一个类可以完成所有事情。这可能已经成为使测试变得比必须的更难的原因。

谈到单元测试时,我喜欢坚持 Michael Feathers 的定义:

A test is not a unit test if:

  • it talks to the database.
  • it communicates across the network.
  • it touches the file system.
  • it can't run at the same time as any of your other unit tests.
  • you have to do special things to your environment (such as editing config files) to run it.

模拟 Ratchet 和 RabbitMQ 连接似乎是使测试符合上述定义的一种方式,但还有另外一句话:“不要模拟你不拥有的东西”。虽然这不是硬性规定,但我认为这是一个很好的指导方针。有很多关于该主题的文章。 This should give you a good overview

不过,Ratchet 在服务器和事件循环部分有点特别。但它经过了很好的测试,因此您不必这样做。我的建议:保持与 Ratchet 的集成非常薄,以至于没有太多东西可以测试,可以跳过测试。

final class MyRatchetApp implements MessageComponentInterface
{
private MessageProcessor $processor;

public function __construct(MessageProcessor $processor)
{
$this->processor = $processor;
}

public function onMessage(ConnectionInterface $from, $msg)
{
$this->processor->handle($msg);
}

// ...
}

这为您留下了一个可以单独测试的 MessageProcessor。它的所有依赖项都是您拥有的类型,因此您可以使用模拟、 stub 或伪造的实现来测试它们的交互。此实现过于简化,遗漏了您肯定想做并且当然想测试的错误处理等内容。

final class MessageProcessor
{
private MessageParser $parser;

private MessageBroadcaster $broadcaster;

public function __construct(MessageParser $parser, MessageBroadcaster $broadcaster)
{
$this->parser = $parser;
$this->broadcaster = $broadcaster;
}

public function handle(string $rawMessage): void
{
$this->broadcaster->send($this->parser->parse($rawMessage));
}
}

interface MessageParser
{
/**
* @throws BadMessageException
*/
public function parse(string $message): Message;
}

interface MessageBroadcaster
{
/**
* @throws UnsupportedMessageException
* @throws UnroutableMessageException
*/
public function send(Message $message): void;
}

创建 MessageParser 的实现应该简单明了并且易于单元测试。 MessageBroadcaster 的 RabbitMQ 实现将是集成测试的完美候选者。

最后,将所有具体实现组合在一起用于实际应用。

$server = IoServer::factory(
new MyRatchetApp(
new MessageProcessor(
new CommandMessageParser(),
new RabbitMqMessageBroadcaster()
)
),
8080
);

为确保所有部分协同工作,您可以创建一些执行完整往返并验证结果的端到端测试。首先创建这些测试,允许您做 Double Loop TDD

关于php - 我不知道如何用 PHPUnit 测试 Ratchet/Sockets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64582575/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com