In this lesson, you will learn how to verify that your error-handling logic correctly catches and reports failures in your unit tests.
When you write functions that return a Result<T, E>, your testing strategy must go beyond checking for successful outcomes. A robust suite also verifies that your code fails exactly when and how you expect it to. In Rust, we achieve this by asserting the variant of the Result returned by our function.
The Result Assertion Pattern
To test a failure path, you invoke your function, capture the Result, and then perform a check on that result. You can use the matches! macro, which is the most concise way to verify that a Result contains a specific error variant.
Consider a simple function that validates a user's age:
#[derive(Debug, PartialEq)]
enum AgeError {
TooYoung,
}
fn validate_age(age: u8) -> Result<u8, AgeError> {
if age < 18 {
Err(AgeError::TooYoung)
} else {
Ok(age)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_age_validation_failure() {
let result = validate_age(15);
// Assert that the result is an Err containing TooYoung
assert!(matches!(result, Err(AgeError::TooYoung)));
}
}
Why use matches! instead of unwrap?
If you were to use .unwrap() on a test that is supposed to fail, the test would panic immediately, which is technically a "failure," but it doesn't give you granular feedback about why the test failed. By using matches! or a match block, you specifically confirm that your code produced the expected error variant.
If you need to verify the specific content of an error (e.g., checking an error message string or an internal code), you can use match or if let statements to extract the data and assert against it directly. This ensures that your error handling isn't just triggered, but that it is producing the correct diagnostic information for the user or the calling system.
Key Takeaway: Use the matches! macro in your unit tests to verify that your functions return the specific Err variants you expect, ensuring your failure paths are as robust as your success paths.