测试返回假



我正在尝试为一个看起来像这样的函数编写一个单元测试:

function read($stream) {
  $line = fgets($stream);
  if (feof($stream)) {
     throw EofException('...');
  }
  if ($line === false) {
     throw new ReadException('Stream error!');
  }
  return $line;
}

调用此函数的一种方法是:

$h = fopen(__FILE__,'r');
$line = read($h);

我正在尝试弄清楚如何在我们没有到达文件末尾的情况下模拟返回 false fgets。我想为ReadException情况编写一个单元测试。

这可能吗?

如果您要测试的代码位于命名空间中,则可以使用此技巧:

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('AppReadException');
        Appread($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);
    }
}

第二个测试也应该通过。

我找到了一种非常简单的方法:

$h = fopen(__FILE__,'a');
read($h);

通过提供仅写入的流,我们可以轻松地fgets返回 false 并触发异常。

相关内容

  • 没有找到相关文章

最新更新