我正在阅读Rust book,并在minigrep的一部分上工作,它要求您在Config::new
函数上编写一些单元测试。我在某些我没想到的事情上失败了,也不理解为什么(Google-fu也在使我失败)。
这失败了
#[cfg(test)]
mod new_config_tests {
use super::*;
#[test]
fn it_can_create_a_new_config() {
let expected_query = "expected_qury";
let expected_filename = "expected_filename.txt";
let args: Vec<String> = vec!["program/path".to_string(), expected_query.to_string(), expected_filename.to_string()];
// failing line
let actual = Config::new(&args).unwrap_or_else(|err| { assert!(false); });
}
}
impl Config {
pub fn new(args: &[String]) -> Result<Config, &'static str> {
if args.len() < 3 {
return Err("not enough arguments\n");
}
let query = args[1].clone();
let filename = args[2].clone();
Ok(Config { query, filename })
}
}
和error[E0308]: mismatched types
--> src/lib.rs:19:62
|
19 | let actual = Config::new(&args).unwrap_or_else(|err| { assert!(false); });
| ^^^^^^^^^^^^^^^^^^^ expected struct `Config`, found `()`
在此测试中,我只是确保可以创建一个新的Config
并希望它在Config::new
函数失败的情况下失败。我认为使用assert
是正确的,以便测试框架可以处理故障。如果我将assert
更改为panic
,那么测试将按预期通过。在上述情况下使用 panic 是否正确?
最佳答案
问题在于,在类型检查期间,编译器尚未(尚未)意识到assert!(false)
总是会失败,因此必须假定它可以通过,从而导致()
类型的值与预期的Config
类型不兼容。
相反,如果将assert替换为对panic
的调用,则编译器会知道panic
永不返回,因此,没有要返回的Config
无关紧要。 (严格来说,panic
类型检查返回的是!
类型的值,也就是“从不”类型,它与所有内容都兼容)。
IMO,您永远不要使用assert!(false)
,而当您知道某种情况总是致命的时,请使用panic
。这使您的意图更加清晰。
尽管在这种特定情况下,最好断言结果是Ok
:
assert!(Config::new(&args).is_ok());
关于rust - 在运行 cargo 测试时在错误分支中使用断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65106806/