debugrustModerate
How to assert io errors in Rust?
Viewed 0 times
asserthowerrorsrust
Problem
There are plenty of tutorials showing how to write unit tests in Rust. I've read dozen and all of them focuses on asserting values in case of success. Situation doesn't seem so straight forward in case of an
Example below.
I assume this is not idiomatic approach, since it's not compiling. Hence the question - what is a proper and idiomatic approach in similar situation?
error. Errors do not implement PartialEq trait by default so you can't use assert_eq! macro. Also, some functions may return multiple variants of error depending on what kind of issue occurred (ex. io::Error which may be of different kind.) I could just check if error occurred or not but it doesn't seem enough.Example below.
fn parse_data(input: i32) -> Result {
match input {
0 => Ok(0),
_ => Err(io::Error::new(io::ErrorKind::InvalidData, "unexpected number"))
}
}
#[test]
fn test_parsing_wrong_data() {
let result = parse_data(1);
assert!(result.is_err());
let got = result.unwrap_err();
let want = io::Error::new(io::ErrorKind::InvalidData, "unexpected number");
// compilation error here: binary operation == cannot be applied to type std::io::Error
assert_eq!(want, got);
}
I assume this is not idiomatic approach, since it's not compiling. Hence the question - what is a proper and idiomatic approach in similar situation?
Solution
TL;DR:
I see a lot of answer and comment that seem a lot of peoples use
For now there is some common crate in Rust to make your own error (feel free to add crate):
I don't totally agree but here a good guide about Error in Rust.
Anyway, the solution that you probably want in your case is just to compare the
Error should implement PartialEqResult only implements PartialEq when T and E also implement PartialEq, but io::Error doesn't. alex confirm that cause io::Error takes an extra error that implements dyn Error, allowing the user to add extra information lead std to not implement PartialEq.I see a lot of answer and comment that seem a lot of peoples use
io::Error to create their own error. This is NOT a good practice, io::Error should be used only if you deal yourself with io. There is the Error Handling Project Group if you want to learn and share your view about error in Rust.For now there is some common crate in Rust to make your own error (feel free to add crate):
- snafu (my favorite)
- thiserror
- anyhow
- quick-error
I don't totally agree but here a good guide about Error in Rust.
Anyway, the solution that you probably want in your case is just to compare the
ErrorKind value. As ErrorKind implements PartialEq this will compile with assert_eq()use std::io;
fn parse_data(input: i32) -> Result {
match input {
0 => Ok(0),
x => Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("unexpected number {}", x),
)),
}
}
#[test]
fn test_parsing_wrong_data() {
let result = parse_data(1).map_err(|e| e.kind());
let expected = Err(io::ErrorKind::InvalidData);
assert_eq!(expected, result);
}
Context
Stack Overflow Q#57234140, score: 36
Revisions (0)
No revisions yet.