将cout和stdout重定向到C++中用于单元测试的字符串

the*_*sdj 28 c++ unit-testing stdout legacy-code

我正在努力在单元测试下获取一些遗留代码,有时感知现有程序行为的唯一方法是从控制台输出.

我在网上看到很多关于如何将stdout重定向到C++中的另一个文件的例子,但有没有办法可以将它重定向到内存中的流,这样我的测试就不必依赖磁盘了?

我希望将遗留代码发送到stdout的任何内容转换为std :: string,这样我就可以轻松地查找输出.

编辑

遗留代码是如此糟糕,以至于用户混合使用cout << ..printf.这是我到目前为止:

void TestSuite::setUp(void)
{
    oldStdoutBuf = std::cout.rdbuf();
    std::cout.rdbuf(consoleOutput.rdbuf());
}
void TestSuite::tearDown(void)
{
    std::cout.rdbuf(oldStdoutBuf);
}
Run Code Online (Sandbox Code Playgroud)

问题是,这并没有用printf捕捉输出.我想要两件兼得的东西.有任何想法吗?

Gab*_*abe 14

std::stringstream 可能就是你要找的东西.

更新
好吧,这是一个黑客攻击,但也许你可以这样做来获取printf输出:

char huge_string_buf[MASSIVE_SIZE];
freopen("NUL", "a", stdout);
setbuf(stdout, huge_string_buffer);
Run Code Online (Sandbox Code Playgroud)

注意你应该使用"/ dev/null"代替"NUL".那将很快开始填满huge_string_buffer.如果你想在缓冲区满后继续重定向输出,你必须调用fflush(),否则会抛出错误.有关详情std::setbuf,请参阅.

  • 运行良好,但如果我使用多个单元测试,有些会因异常而失败,因为缓冲区已经被释放并且stdout被写入其中.如果只是临时重定向到缓冲区,请在使用结束时使用`setbuf(stdout,NULL);`. (3认同)