如何触发Rust中stdin().read_line()的expect错误?
如何触发Rust程序中stdin.read_line()的错误分支
手动触发(终端环境)
要在手动运行时触发read_line()的错误分支,核心是让标准输入(stdin)出现IO错误,而非仅输入EOF(EOF会让read_line()返回Ok(0),不会触发panic)。以下是两种可行方法:
方法1:重定向stdin到无权限的文件
在Unix-like系统(Linux/macOS)中,编译程序后,运行时将stdin指向一个你没有读取权限的文件:rustc your_program.rs ./your_program < /root/protected_file.txt此时
read_line()会因权限不足返回Err(PermissionDenied),触发expect()的panic,输出指定错误信息。方法2:关闭stdin文件描述符
同样在Unix-like系统中,直接关闭stdin后运行程序:./your_program <&-此时stdin是无效的文件描述符,
read_line()会返回错误,触发panic。
在测试用例中触发
直接测试原程序的prompt()函数需要模拟错误的输入源,最方便的方式是重构函数使其依赖注入Read trait,这样测试时可以传入自定义的错误实现:
重构后的代码
use std::io::{self, Read, stdout, Write}; fn main() { loop { let mut command = prompt(io::stdin()); println!("--> {}", command); } } // 重构为接受任意Read类型的参数,便于测试 fn prompt<R: Read>(mut reader: R) -> String { let mut buffer = String::new(); print!("++> "); let _ = stdout().flush(); reader.read_line(&mut buffer).expect("Error retrieving input."); buffer.clone() }
测试用例
#[cfg(test)] mod tests { use super::*; use std::io::{self, Read}; // 自定义一个总是返回IO错误的Read实现 struct ErrorReader; impl Read for ErrorReader { fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Err(io::Error::new(io::ErrorKind::Other, "Simulated input error")) } } #[test] fn test_prompt_triggers_panic() { // 捕获panic,验证是否触发了错误分支 let result = std::panic::catch_unwind(|| { prompt(ErrorReader); }); assert!(result.is_err()); } }
运行测试后,会验证prompt()在输入错误时确实触发了panic。
内容的提问来源于stack exchange,提问作者Nathaniel Ford
相关产品推荐
相关产品推荐

