Capturing IO is most often necessary while testing. Instead of hand-coding a function using pipe and dup (because setting rdbuf will only work for C++ streams), rely on the functions packaged in Google Test.

So, there are death tests that check against stderr like EXPECT_DEATH:

TEST(Diagnostic, NotAFunction)
  std::string SourcePrg =
    "defun main [] {\n"
    "  foo = 2;\n"
    "  foo 4;\n"
  std::string ExpectedErr =
    "string stream:3:3:.*error:.*foo was not declared as a function";
  EXPECT_DEATH(rhine::parseCodeGenString(SourcePrg), ExpectedErr);

There are various ways to check all kinds of abnormal exits. However, there is no builtin to check for normal returns (termed LIVED in; but we can code a limited version ourselves using the internal CaptureStdout and GetCapturedStdout:

#include "gtest/internal/gtest-port.h"

void EXPECT_OUTPUT(std::string &SourcePrg, std::string &ExpectedOut)
  auto Handle = rhine::jitFacade(SourcePrg, false, true);
  std::string ActualOut = testing::internal::GetCapturedStdout();
  EXPECT_STREQ(ExpectedOut.c_str(), ActualOut.c_str());