如何使用PHPUnit对套接字代码进行单元测试? [英] How do I unit test socket code with PHPUnit?

查看:81
本文介绍了如何使用PHPUnit对套接字代码进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有一个Socket类,它基本上只是PHP socket_*函数的OO包装器类:

I currently have a Socket class, which is basically just an OO wrapper class for PHP's socket_* functions:

class Socket {
    public function __construct(...) {
        $this->_resource = socket_create(...);
    }

    public function send($data) {
        socket_send($this->_resource, $data, ...);
    }

    ...
}

由于我使用的是PHP的套接字函数,所以我不认为我可以模拟套接字资源,所以现在我被困在如何可靠地对此类进行单元测试的问题上.

I don't think I can mock the socket resource since I'm using PHP's socket functions, so right now I'm stuck as to how to reliably unit test this class.

推荐答案

您似乎在单元测试心态中缺少一小部分.

You appear to be missing a small piece to the unit test mindset.

通过创建Stub对象,可以轻松解决您的问题.奇怪的是,我一次又一次给出这个答案,所以很多人一定会错过它.

Your problem is easily solvable by creating a Stub object. Strangely, I give this answer time and time again, so it must be largely missed by a lot of people.

因为我对存根和模拟之间的区别感到非常困惑,所以我也将其放在这里...

Because I see so much confusion as to the differences between stubs and mocks, let me lay it out here, as well...

  • 模拟是用于扩展测试直接依赖的另一个类的类,以更改该类的行为使测试更容易.
  • 存根是*实现API或接口**的类,该类不能通过测试直接直接轻松地进行测试,以便可以进行测试.
  • A mock is a class that extends another class that the test is directly dependent on, in order to change behaviors of that class to make testing easier.
  • A stub is a class that *implements an API or interface** that a test cannot test easily directly on its own, in order to make testing possible.

^-这是我读过的两个书中最清楚的描述;我应该把它放到我的网站上.

^-- That is the clearest description of the two I've ever read; I should put it on my site.

套接字具有这一不错的功能,您可以在其中绑定端口0以进行测试(严重地,它称为临时端口").

Sockets have this nice feature where you can bind to port 0 for testing purposes (seriously, it's called the "ephemeral port").

所以尝试一下:

class ListeningServerStub
{
    protected $client;

    public function listen()
    {
        $sock = socket_create(AF_INET, SOCK_STREAM, 0);

        // Bind the socket to an address/port
        socket_bind($sock, 'localhost', 0) or throw new RuntimeException('Could not bind to address');

        // Start listening for connections
        socket_listen($sock);

        // Accept incoming requests and handle them as child processes.
        $this->client = socket_accept($sock);
    }

    public function read()
    {
        // Read the input from the client – 1024 bytes
        $input = socket_read($this->client, 1024);
        return $input;
    }
}

创建此对象并将其设置为在测试的setUp()中进行监听,然后停止监听并在tearDown()中销毁它.然后,在测试中,连接到假服务器,通过read()函数取回数据,然后进行测试.

Create this object and set it to listen in your test's setUp() and stop listening and destroy it in the tearDown(). Then, in your test, connect to your fake server, get the data back via the read() function, and test that.

如果这对您有很大帮助,请考虑在传统的框框之外给我悬赏;-)

If this helps you out a lot, consider giving me a bounty for thinking outside the traditional box ;-)

这篇关于如何使用PHPUnit对套接字代码进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆