I had a method, that opened a socket connection, used, and then closed it. In order to make it testable, I moved the dealing with the connection to separate methods (see the code below).
Now I want to write a unit test for the barIntrefaceMethod()
and need to mock the method openConnection()
. With other words, I need a fake resource
.
Is it possible / How to "manually" create a variable of the type resource
in PHP (in order to fake handles like "opened files, database connections, image canvas areas and the like" etc.)?
FooClass
class FooClass
{
public function barIntrefaceMethod()
{
$connection = $this->openConnection();
fwrite($connection, 'some data');
$response = '';
while (!feof($connection)) {
$response .= fgets($connection, 128);
}
return $response;
$this->closeConnection($connection);
}
protected function openConnection()
{
$errno = 0;
$errstr = null;
$connection = fsockopen($this->host, $this->port, $errno, $errstr);
if (!$connection) {
// TODO Use a specific exception!
throw new Exception('Connection failed!' . ' ' . $errno . ' ' . $errstr);
}
return $connection;
}
protected function closeConnection(resource $handle)
{
return fclose($handle);
}
}
As per my comments, I think you would be better off refactoring your code a little to remove the dependency on native functions being actually called with an actual resource handle. All you care about for the test of the
FooClass::barInterfaceMethod
is that it returns a response. That class need not concern itself with whether the resource is opened, closed, written to, etc. So that is what should be mocked out.Below I have rewritten what you have in your question to demonstrate, in some simplistic and non-production pseudo-code:
Your real class:
Your test of this class:
For the actual
Resource
class, you don't need to then unit test those methods that are wrappers around native functions. Example:Lastly, the other alternative if you want to keep your code as-is is to setup test fixture resources that you actually connect to for test purposes. Something like
Where
$some_test_host
contains some data you can mess with for tests.