How to unit test socket code with PHPUnit?

I currently have a Socket class, which is basically an OO shell class for PHP functions socket_* :

 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 a socket resource, since I use the functions of PHP sockets, so right now I am fixated on how reliably unit test this class is.

+7
source share
1 answer

It seems that you do not see a small part of the unit test thinking.

Your problem is easily resolved by creating a Stub object. Strange, I give this answer again and again, so it should be largely missed by many people.

Since I see so much confusion about the differences between stubs and layouts, let me also put this here ...

  • A layout is a class that extends another class that tests directly dependent to change the behavior of this class to simplify testing .
  • A piece is a class that implements an API or interface * that a test cannot easily test on its own to make testing possible ..>

^ - This is the clearest description of the two I've ever read; I have to post it on my website.

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

So try the following:

 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($client, 1024); return $input; } } 

Create this object and set it to listen in your setUp() test and stop listening and destroy it in tearDown() . Then, in your test, connect to your fake server, return the data through the read() function, and verify this.

If this helps you, consider giving me the bounty to think outside the traditional box; -)

+16
source

All Articles