测试时全局禁用c++ std::cout

globally suppress c++ std::cout when testing

本文关键字:std cout c++ 全局 测试      更新时间:2023-10-16

我有一个Struct点在数值数据与一个returnNext()方法,返回和职位在stdout下一个数据每次调用。我还有一系列使用此方法的单元测试:在这些测试中,我想抑制所有Data的std::cout,以便我只检查返回值的有效性,而不会用消息填充屏幕。例如

struct Data { 
  Data(int n): datum{n} {};
  int datum;
  int returnNext() { 
    std::cout << datum << " returned" << std::endl;
    return datum;
  }
}
// main.cpp
int main() {
  Data d{100};
  d.returnNext(); // I want this to print at the screen 
  return 0;
}
// test.cpp
int main() {
  TEST( ... ) {
    Data d{100};
    ASSERT_THAT(d.returnNext(), 100); // I want just to check the output, not to check
  }
std::cout << "some message" << std::endl; // I want this printed
return 0;
}

一个明显的解决方案是使用预编译器标志/命令从测试构建中排除std::cout。但这将需要编辑几个模块,也会使我的代码变得丑陋。

另一种情况是从控制台使用重定向标准输出到dev/null,但这也会抑制测试模块的标准输出。

在程序生命周期的特定时刻,是否有一种方法可以编程地抑制/重定向标准输出?

对于抑制std::cout的一般问题,您可以使用带有空缓冲区的std::basic_ios::rdbuf:

auto old_buffer = std::cout.rdbuf(nullptr);

要恢复它,只需执行

std::cout.rdbuf(old_buffer);

这就是为什么在成员函数中硬编码标准输出输出是一个坏主意的原因。现在你认为你必须全局阻止std::cout,因为你的类的行为是不灵活的。

相反,将std::cout调用移动到其他地方(使其使用可选)或将其作为任意的std::ostream,您可以将其路由到任何地方。