Reputation: 23
I'm reading through the Rust book and working on part of the minigrep where it asks you to write some unit tests on the Config::new
function. I'm failing on something that I didn't expect and don't understand why (Google-fu is failing me as well).
This fails
#[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 })
}
}
with
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 `()`
In this test, I'm just making sure that I can create a new Config
and want it to fail if the Config::new
function fails. I thought that using assert
would be correct so that the test framework would handle the failure. If I change the assert
to panic
, then the tests pass as expected. Is using panic correct in the above scenario?
Upvotes: 0
Views: 1304
Reputation: 23294
The problem is that during type-checking, the compiler doesn't (yet) realize that assert!(false)
will always fail, so it has to assume that it may pass, resulting in a value of type ()
which is incompatible with the expected Config
type.
Conversely, if you replace the assert with a call to panic
, the compiler knows that panic
never returns, so it doesn't matter if there is no Config
to return. (Strictly speaking, panic
typechecks as returning a value of type !
, aka the "never" type, which is compatible with everything).
IMO you should never use assert!(false)
, and instead use panic
when you know that a condition is always fatal. This makes your intent clearer.
Although in this specific case, it would probably be better to assert that the result is Ok
:
assert!(Config::new(&args).is_ok());
Upvotes: 3