你不能在 phpunit 的帮助下从测试用例中截取和fwrite(STDERR);。就此而言,您甚至无法拦截 fwrite(STDOUT);,即使使用输出缓冲也不行。
因为我假设您并不想将STDERR 注入您的“errorOutputWriter”(因为在其他地方写该类没有任何意义)这是极少数情况之一我建议这种小技巧:
<?php
class errorStreamWriterTest extends PHPUnit_Framework_TestCase {
public function setUp() {
$this->writer = new errorStreamWriter();
$streamProp = new ReflectionProperty($this->writer, 'errorStream');
$this->stream = fopen('php://memory', 'rw');
$streamProp->setAccessible(true);
$streamProp->setValue($this->writer, $this->stream);
}
public function testLog() {
$this->writer->log("myMessage");
fseek($this->stream, 0);
$this->assertSame(
"Error: myMessage",
stream_get_contents($this->stream)
);
}
}
/* Original writer*/
class errorStreamWriter {
public function log($message) {
fwrite(STDERR, "Error: $message");
}
}
// New writer:
class errorStreamWriter {
protected $errorStream = STDERR;
public function log($message) {
fwrite($this->errorStream, "Error: $message");
}
}
它取出 stderr 流并将其替换为内存中的流,然后在测试用例中读回该流以查看是否写入了正确的输出。
通常我肯定会说“在类中注入文件路径”,但 STDERR 对我来说没有任何意义,所以这将是我的解决方案。
phpunit stderrTest.php
PHPUnit @package_version@ by Sebastian Bergmann.
.
Time: 0 seconds, Memory: 5.00Mb
OK (1 test, 1 assertion)
更新
经过一番思考后,我会说没有像 errorSteamWriter 这样的思考作为一个班级也可能会奏效。
只要有一个StreamWriter 并用new StreamWriter(STDERR); 构造它,就会产生一个可很好测试的类,它可以在应用程序中用于很多目的,而无需硬编码某种“这是错误发生的地方”到类它是自我并增加灵活性。
只是想将此作为选项添加以避免“丑陋”的测试选项:)