首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何测试Box<dyn Error>中的错误类型?

如何测试Box<dyn Error>中的错误类型?
EN

Stack Overflow用户
提问于 2021-07-20 11:09:38
回答 2查看 1K关注 0票数 0

我有一个返回Result<(), Box<dyn Error>>的函数。我正在为这个函数编写一个测试用例,其中函数应该返回VerifyError::LinearCombinationError (游乐场)类型的错误:

代码语言:javascript
运行
复制
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};

#[derive(Debug, PartialEq, Eq)]
enum VerifyError {
    LinearCombination,
}

impl Error for VerifyError {}

impl Display for VerifyError {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

fn return_result() -> Result<(), Box<dyn Error>> {
    Err(Box::new(VerifyError::LinearCombination))
}

pub fn main() {
    let res = return_result();
    println!("debug print is: {:?}", res);

    // Program does not compile when below line is not commented out
    // assert_eq!(Some(VerifyError::LinearCombination), res.err());
}

取消对行的注释将提供错误消息:

代码语言:javascript
运行
复制
error[E0308]: mismatched types
  --> src/main.rs:26:5
   |
26 |     assert_eq!(Some(VerifyError::LinearCombination), res.err());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `VerifyError`, found struct `Box`
   |
   = note: expected enum `Option<VerifyError>`
              found enum `Option<Box<dyn std::error::Error>>`
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

我正在使用Rust 1.53.0。

EN

Stack Overflow用户

回答已采纳

发布于 2021-07-20 12:36:24

使用Error::is测试错误特征对象是否具有特定的具体类型,或者使用Error::downcast将其转换为该具体类型:

代码语言:javascript
运行
复制
use std::error::Error;

fn example() -> Result<(), Box<dyn Error>> {
    Err(std::io::Error::last_os_error().into())
}

#[test]
fn is_from_io_error() {
    let e = example().err().unwrap();
    assert!(e.is::<std::io::Error>());

    let _e = e.downcast::<std::io::Error>().unwrap();
}

如果您关心特定的错误,我会鼓励您避免使用属性对象。特征对象的要点是,您不需要知道具体类型是什么。

相反,您可以使用一个库来帮助您构造错误类型,例如我的斯纳福。此用法显示枚举中的包装错误,这些错误可以与测试特定类型的模式匹配:

代码语言:javascript
运行
复制
use snafu::{Snafu, ResultExt}; // snafu = "0.7.0-beta.0"

#[derive(Debug, Snafu)]
enum Error {
    Example { source: std::io::Error }
}

fn example() -> Result<(), Error> {
    Err(std::io::Error::last_os_error()).context(ExampleSnafu)
}

#[test]
fn is_from_io_error() {
    let e = example();
    assert!(matches!(e, Err(Error::Example { .. })))
}
票数 4
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68453846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档