如果您正在测试的代码在命名空间中,您可以使用这个技巧:
namespace App {
//fgets is a "mock" for the one from global namespace
function fgets($handle, $length = 1024) {
return false;
}
class ReadException extends \Exception {
}
function read($stream) {
//this calls the function in the namespace because it exists
//otherwise falls back to the global one
$line = fgets($stream);
if (feof($stream)) {
throw EofException('...');
}
if ($line === false) {
throw new ReadException('Stream error!');
}
return $line;
}
}
那么您在全局命名空间中的测试将如下所示:
class FileTest extends PHPUnit_Framework_TestCase {
public function testReadErrorThrowsReadException() {
$handler = fopen(__FILE__, 'r');
$this->setExpectedException('App\ReadException');
App\read($handler);
}
}
上面的测试应该通过了。
现在,如果您无权访问命名空间,我认为您必须重写读取函数以使用“读取器”对象。像这样的:
function read($stream, FileReader $reader) {
$line = $reader->fgets($stream);
if (feof($stream)) {
throw EofException('...');
}
if ($line === false) {
throw new ReadException('Stream error!');
}
return $line;
}
interface FileReader {
public function fgets($handle, $length = 1024);
}
那么测试将是:
class FileTest extends PHPUnit_Framework_TestCase {
public function testReadErrorThrowsReadException() {
$handler = fopen(__FILE__, 'r');
$readerMock = $this->getMock('FileReader');
$readerMock->expects($this->once())
->method('fgets')
->with($handler)
->will($this->returnValue(false));
$this->setExpectedException('ReadException');
read($handler, $readerMock);
}
}
第二个测试也应该通过。