如何测试特定的Rust错误?

时间:2018-11-02 19:42:33

标签: unit-testing testing error-handling rust

我可以找到方法来检测Rust是否给我一个错误,

assert!(fs::metadata(path).is_err())

source

如何测试特定错误?

2 个答案:

答案 0 :(得分:4)

您需要使用OptionResult获取.err并将其与Some(MyError)

进行比较。
#[derive(Debug, PartialEq)]
enum MyError {
    TooBig,
    TooSmall,
}
pub fn encode(&self, decoded: &'a Bytes) -> Result<&'a Bytes, MyError> {

    if decoded.len() > self.length() as usize {
        Err(MyError::TooBig)
    } else {
        Ok(&decoded)
    }
}
assert_eq!(fixed.encode(&[1]), Err(MyError::TooBig));

答案 1 :(得分:2)

以下解决方案不需要实现 PartialEq 特性。例如 std::io::Error 没有实现这一点,需要更通用的解决方案。

在这些情况下,您可以从 matches crate 借用宏 assert_matches。它通过提供更简洁的模式匹配方式来工作,宏很短,你也可以输入它:

macro_rules! assert_err {
    ($expression:expr, $($pattern:tt)+) => {
        match $expression {
            $($pattern)+ => (),
            ref e => panic!("expected `{}` but got `{:?}`", stringify!($($pattern)+), e),
        }
    }
}

// Example usages:
assert_err!(your_func(), Err(Error::UrlParsingFailed(_)));
assert_err!(your_func(), Err(Error::CanonicalizationFailed(_)));
assert_err!(your_func(), Err(Error::FileOpenFailed(er)) if er.kind() == ErrorKind::NotFound);

完整的游乐场可构建示例,示例为 Error 枚举:

#[derive(Debug)]
pub enum Error {
    UrlCreationFailed,
    CanonicalizationFailed(std::io::Error),
    FileOpenFailed(std::io::Error),
    UrlParsingFailed(url::ParseError),
}

pub fn your_func() -> Result<(), Error> {
    Ok(())
}

#[cfg(test)]
mod test {
    use std::io::ErrorKind;
    use super::{your_func, Error};

    macro_rules! assert_err {
        ($expression:expr, $($pattern:tt)+) => {
            match $expression {
                $($pattern)+ => (),
                ref e => panic!("expected `{}` but got `{:?}`", stringify!($($pattern)+), e),
            }
        }
    }

    #[test]
    fn test_failures() {
        // Few examples are here:
        assert_err!(your_func(), Err(Error::UrlParsingFailed(_)));
        assert_err!(your_func(), Err(Error::CanonicalizationFailed(_)));
        assert_err!(your_func(), Err(Error::FileOpenFailed(er)) if er.kind() == ErrorKind::NotFound);
    }

}