我的目标是测试转到标准输出的函数的输出。到目前为止,我最好的尝试是在测试中用字符串替换流。
到目前为止,这是我设法实现的目标:
use std::io;
use std::fmt;
fn hello(stdout: &mut std::fmt::Write) {
writeln!(stdout, "Hello world");
}
#[test]
fn hello_test() {
let mut stdout = String::new();
// pass fake stdout when calling when testing
hello(&mut stdout);
assert_eq!(stdout, "Hello world\n".to_string());
}
fn main() {
// pass real stdout when calling from main
hello(&mut io::stdout());
}
Run Code Online (Sandbox Code Playgroud)
测试有效,但不幸的io::stdout()是没有实现该fmt::Write特征。
测试在Rust中写入标准输出的函数的最佳解决方案是什么?有没有办法用字符串修复我的解决方案,还是应该寻找替代方法?
在write!宏观预期目标操作数来实现两种 std::fmt::Write或std::io::Write。自writeln!代表以来write!,这也适用于writeln!。
的文档std::fmt::Write说:
该
io::Write性状优于实施这一特质
自Stdout实施以来std::io::Write,您应该将代码范围从更改fmt::Write为io::Write。但是请注意,String它没有实现io::Write,因为io::Write它可以接受格式不正确的UTF-8的任意字节。您可以Vec<u8>改用。
use std::io;
fn hello(stdout: &mut io::Write) {
writeln!(stdout, "Hello world");
}
#[test]
fn hello_test() {
let mut stdout = Vec::new();
// pass fake stdout when calling when testing
hello(&mut stdout);
assert_eq!(stdout, b"Hello world\n");
}
fn main() {
// pass real stdout when calling from main
hello(&mut io::stdout());
}
Run Code Online (Sandbox Code Playgroud)
为了提高性能,如果仅一个线程需要在stdout上写,请考虑将a StdoutLock而不是a 传递Stdout给您的函数(使用Stdout,每个写都获取并释放一个锁)。
如果您确实更喜欢使用它std::fmt::Write,则可以使用将fmt::Write调用转换为io::Write调用的适配器结构。
use std::io;
use std::fmt;
struct WriteAdapter<W>(W);
impl<W> fmt::Write for WriteAdapter<W>
where
W: io::Write,
{
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error)
}
fn write_fmt(&mut self, args: fmt::Arguments) -> Result<(), fmt::Error> {
self.0.write_fmt(args).map_err(|_| fmt::Error)
}
}
fn hello(stdout: &mut fmt::Write) {
writeln!(stdout, "Hello world");
}
#[test]
fn hello_test() {
let mut stdout = String::new();
// pass fake stdout when calling when testing
hello(&mut stdout);
assert_eq!(stdout, "Hello world\n");
}
fn main() {
// pass real stdout when calling from main
hello(&mut WriteAdapter(io::stdout()));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
590 次 |
| 最近记录: |