foo我有一个无法修改的函数,并且包含其中的代码println!。eprintln!
fn foo() {
println!("hello");
}
Run Code Online (Sandbox Code Playgroud)
调用该函数后,我必须测试它打印的内容,因此我想将 stdout/stderr 捕获到变量中。
我强烈建议不要这样做,但如果您使用 nightly 并且不介意使用似乎不太可能稳定的功能,您可以使用标准库的隐藏功能直接捕获 stdout 和 stderr:
#![feature(internal_output_capture)]
use std::sync::Arc;
fn foo() {
println!("hello");
eprintln!("world");
}
fn main() {
std::io::set_output_capture(Some(Default::default()));
foo();
let captured = std::io::set_output_capture(None);
let captured = captured.unwrap();
let captured = Arc::try_unwrap(captured).unwrap();
let captured = captured.into_inner().unwrap();
let captured = String::from_utf8(captured).unwrap();
assert_eq!(captured, "hello\nworld\n");
}
Run Code Online (Sandbox Code Playgroud)
函数“无法更改”的情况非常罕见,因此我鼓励您这样做并改用依赖注入。例如,如果您能够编辑foo但不想更改其签名,请将所有代码移动到带有泛型的新函数中,您可以直接测试该泛型:
use std::io::{self, Write};
fn foo() {
foo_inner(io::stdout(), io::stderr()).unwrap()
}
fn foo_inner(mut out: impl Write, mut err: impl Write) -> io::Result<()> {
writeln!(out, "hello")?;
writeln!(err, "world")?;
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
也可以看看: