rust - 在运行 cargo 测试时在错误分支中使用断言

标签 rust

我正在阅读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/

相关文章:

rust - 在 Rust 中读取字符串并将其解析为迭代器的函数

iterator - iter().cloned().filter().map() 的返回类型应该是什么

generics - 如何将 Rc<RefCell<ConcreteType>> 转换为 Rc<RefCell<dyn Trait>>?

rust - 无法安装Racer : "pub(restricted) syntax is experimental (see issue #32409)"

sorting - 如何对向量的一部分进行排序?

rust - 在 Arc 和 Mutex 后面调用 Trait 对象的方法

rust - 为什么我可以在 Rust 中从向量的末尾开始切片?

rust - 从结构方法中创建和分配引用数据

string - 正则表达式捕获不会像我认为的那样长

alias - Rust 中的类型别名