New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to unit test expected failures? #254

Open
paulkernfeld opened this Issue Sep 8, 2018 · 1 comment

Comments

Projects
None yet
1 participant
@paulkernfeld

paulkernfeld commented Sep 8, 2018

When I'm writing code, I often want to be able to test that it returns a the right error in a particular situation. With hand-implemented errors, I would use a match statement for this, since errors can't be expected to implement PartialEq. Normally I would make this more informative and concise by using assert_matches from the matches crate. For example:

use std::error::Error;
use std::fmt;
use std::fmt::{Display, Formatter};

#[derive(Debug)]
pub enum MyError {
    BadThingHappened {
        badness_level: usize,
    },
}

impl Display for MyError {
    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
        unimplemented!()  // I have omitted this
    }
}

impl Error for MyError {
}

fn my_fn() -> Result<(), MyError> {
    Err(MyError::BadThingHappened {
        badness_level: 9
    })
}

fn main() {
    match my_fn() {
        Err(MyError::BadThingHappened { badness_level: 9 }) => (),
        _ => panic!("the wrong error was returned")
    }
}

How could I test this behavior with a failure error? For example:

#[macro_use] extern crate failure;

use failure::Error;

#[derive(Debug, Fail)]
pub enum MyError {
    #[fail(display = "a bad thing of level {} happened", badness_level)]
    BadThingHappened {
        badness_level: usize,
    },
}

fn my_fn() -> Result<(), Error> {
    Err(Error::from(MyError::BadThingHappened {
        badness_level: 9
    }))
}

fn main() {
    // What would I put here to test that my_fn has returned the correct error?
}
@paulkernfeld

This comment has been minimized.

paulkernfeld commented Sep 9, 2018

Would using downcast_ref be a good way to do this? It appears to work for the use case above.

fn main() {
    match my_fn()
        .expect_err("my_fn should return an error")
        .downcast_ref()
        .expect("the wrong type of error was returned")
    {
        MyError::BadThingHappened { badness_level: 9 } => (),
        _ => panic!("the wrong error was returned"),
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment