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.
You can run all the tests in a directory using the PHPUnit binary installed in your vendor folder. You can also run a single test by providing the path to the test file.
PHPUnit is a unit testing framework for the PHP programming language. It is an instance of the xUnit design for unit testing systems that began with SUnit and became popular with JUnit. Even a small software development project usually takes hours of hard work.
PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. PHPUnit 9 is the current stable version. PHPUnit 10 is currently in development.
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...
^-- 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 ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With