【发布时间】:2018-11-02 19:42:33
【问题描述】:
【问题讨论】:
-
您可以使用宏#[should_panic]。你可以看看stackoverflow.com/a/26470361/8402395
标签: unit-testing testing error-handling rust
【问题讨论】:
标签: unit-testing testing error-handling rust
如果是impl Debug + PartialEq,可以直接比较返回的Err变体:
#[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));
【讨论】:
Result 和.err 获取Option — 为什么不直接比较呢?
Option 不是Result 的变体。不确定我是否理解你的问题。昨天也刚开始编程 Rust,所以这里可能会遗漏一些明显的东西
Err(MyError::TooBig)比较呢?
expected enum 'std::result::Result', found enum 'fixed::Error'
Err(MyError::TooBig) 与MyError::TooBig 不同
以下解决方案不需要实现 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);
}
}
【讨论】: