Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you test for a specific Rust error?

Tags:

I can find ways to detect if Rust gives me an error,

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

source

How do I test for a specific error?

like image 964
Aakil Fernandes Avatar asked Nov 02 '18 19:11

Aakil Fernandes


People also ask

How can you test for Rust?

A primary testing method is Salt Spray testing, which as its name indicates, evaluates how resistant a part or material is to corrosion when exposed to a salt spray for extended periods of time. Effective Salt Spray testing must be performed in a controlled environment, such as a closed salt fog tank.

Does Rust have runtime errors?

With Rust, most of these runtime errors are converted to compile-time errors, and once code compiles, it works, and for real. - Data races are programmatically impossible because of the ownership system in Rust! Rust is fast, it's a systems programming language, meaning memory management is made manually.

How do you run a ignored test in Rust?

If you want to run all tests whether they're ignored or not, you can run cargo test -- --include-ignored .

Does Rust have error handling?

Errors are a fact of life in software, so Rust has a number of features for handling situations in which something goes wrong. In many cases, Rust requires you to acknowledge the possibility of an error and take some action before your code will compile.


2 Answers

You can directly compare the returned Err variant if it impl Debug + PartialEq:

#[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));
like image 174
Aakil Fernandes Avatar answered Oct 28 '22 00:10

Aakil Fernandes


Following solution doesn't require PartialEq trait to be implemented. For instance std::io::Error does not implement this, and more general solution is required.

In these cases, you can borrow a macro assert_matches from matches crate. It works by giving more succinct way to pattern match, the macro is so short you can just type it too:

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);

Full playground buildable example, with example Error enum:

#[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);
    }

}
like image 21
Ciantic Avatar answered Oct 28 '22 00:10

Ciantic