How to test functions that use println!()

When I was working on a toy project that used macros to generate println! calls, I came up with this solution using the gag library.

I whipped up this assert_stdout_eq! macro:

#[macro_export]
macro_rules! assert_stdout_eq {
    ($test:expr, $expected:literal) => {{
        use gag::BufferRedirect;
        use std::io::Read;

        let mut buf = BufferRedirect::stdout().unwrap();

        $test;

        let mut output = String::new();
        buf.read_to_string(&mut output).unwrap();
        drop(buf);

        assert_eq!(&output[..], $expected);
    }};
}

So I could put this in my tests:

assert_stdout_eq!(my_macro!("KEY", "VALUE"), "KEY=VALUE\n");
}

Then I put this in my build.rs so that I could just run cargo test without any extra options:

fn main() {
    println!("cargo:rustc-env=RUST_TEST_NOCAPTURE=1");
}
2 Likes