doudang4568 2012-02-03 22:26
浏览 18
已采纳

如何使用PHPUnit对套接字代码进行单元测试?

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, ...);
    }

    ...
}

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.

  • 写回答

1条回答 默认 最新

  • dsfdsf46465 2012-02-04 19:28
    关注

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

    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...

    • 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.

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

    So try this:

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

    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 ;-)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 Unity接入微信SDK 无法开启摄像头
  • ¥20 有偿 写代码 要用特定的软件anaconda 里的jvpyter 用python3写
  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源