Reputation: 1734
I've created a custom error type using an enum to support multiple error conditions (omitted in example) but I am not able to test the following code without providing the data (in this case a str::Utf8Error
) to the enum to perform a comparison.
use std::fmt;
use std::str;
#[derive(Debug, PartialEq)]
pub enum ClaimsError {
ParseError(str::Utf8Error),
// Other variants omitted.
}
impl std::error::Error for ClaimsError {}
impl fmt::Display for ClaimsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ClaimsError::ParseError(ref err) => err.fmt(f),
}
}
}
pub fn from_slice(token: &[u8]) -> Result<&str, ClaimsError> {
str::from_utf8(&token).map_err(|e| ClaimsError::ParseError(e))
}
#[cfg(test)]
mod tests {
use super::{from_slice, ClaimsError};
#[test]
fn bad_token_fails() {
assert_eq!(
from_slice(&[0xF8]).unwrap_err(),
ClaimsError::ParseError // <-- Here is the problem line.
);
}
}
fn main() {
match from_slice(&[0xF8]) {
Ok(_) => println!("great"),
Err(ClaimsError::ParseError(err)) => println!("{}", err),
}
}
Understandably the types do not match, thus causing the issue, so in an attempt to fix it I've tried changing the assertion to:
#[test]
fn bad_token_fails() {
assert_eq!(
from_slice(&[0xF8]).unwrap_err(),
ClaimsError::ParseError(str::Utf8Error{})
);
}
However it is not possible to create a str::Utf8Error
this way because it contains only private fields. For the sake of my test I don't need to match the exact error, I am only concerned whether the error value returned from from_slice
is of type ClaimsError::ParseError
.
I've taken a look at the Error
trait and in particular the is
method stood out to me but I'm not sure if this is what I want or how to use it in this case. Any help solving this is appreciated.
(link) to a rust playground with the above code.
Upvotes: 2
Views: 147
Reputation: 1581
You can use pattern matching
to match
on the result of from_slice(&[0xF8]).unwrap_err()
#[test]
fn bad_token_fails() {
match from_slice(&[0xF8]).unwrap_err() {
ClaimsError::ParseError(_) => assert!(true),
_ => assert!(false)
}
}
This test succeeds if the result is of type ClaimsError::ParseError
and fails if the result is of other types.
As @Cerberus stated, you could also use the matches!
macro, to avoid using assert!(true)
and assert!(false)
:
#[test]
fn bad_token_fails() {
assert!(matches!(
from_slice(&[0xF8]),
Err(ClaimsError::ParseError(_))
));
}
Upvotes: 3