我有一个异步函数,它在完成所有的web解析之后返回一个结构。在运行测试时,我得到了错误:no implementation for `dyn std::error::Error == dyn std::error::Error`。我怎么能解决这个问题,或者我做错了什么?
#[derive(Debug, PartialEq, Eq)]
pub struct ParsingResult<'a> {
title: &'a str,
content: String,
}
impl<'a> ParsingResult<'a> {
pub fn new(title: &'a str, content: String) -> Self {
ParsingResult { title, content }
}
}
pub async fn yahoo_template<'a>(
link_to_the_article: &str,
) -> Result<ParsingResult<'a>, Box<dyn error::Error>> {
let resp = reqwest::get(link_to_the_article).await?.text().await?;
let mut final_res: Vec<String> = Vec::new();
Document::from(resp.as_str())
.find(Name("a"))
.filter_map(|n| n.attr("href"))
.for_each(|x| {
if x.contains("http") || x.contains("https") {
final_res.push(String::from(x));
}
});
// println!("{:?}", final_res);
Ok(ParsingResult::new("Title", String::from("String")))
}
#[cfg(test)]
mod templates_tests {
use super::*;
#[tokio::test]
async fn make_it_work() {
let expected = Ok(ParsingResult::new("Title", String::from("String")));
assert_eq!(
expected,
yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await
);
}
}错误输出:
error[E0277]: can't compare `dyn std::error::Error` with `dyn std::error::Error`
--> src/scraper/scraping_templates.rs:47:3
|
47 | / assert_eq!(
48 | | expected,
49 | | yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await
50 | | );
| |_________^ no implementation for `dyn std::error::Error == dyn std::error::Error`
|
= help: the trait `PartialEq` is not implemented for `dyn std::error::Error`
= note: required because of the requirements on the impl of `PartialEq` for `Box<dyn std::error::Error>`
= note: 1 redundant requirement hidden
= note: required because of the requirements on the impl of `PartialEq` for `Result<scraping_templates::ParsingResult<'_>, Box<dyn std::error::Error>>`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)发布于 2022-06-15 16:43:05
此错误来自async fn make_it_work()中的async fn make_it_work()调用。
此断言试图比较两个Result<ParsingResult<'a>, Box<dyn error::Error>>值是否相等。Result只在Ok和Err变体的类型可以与自身进行相等比较时才实现相等比较。这意味着ParsingResult<'a>必须为自己实现PartialEq (由于您的#[derive]而实现),而Box<dyn error::Error>也必须实现PartialEq --但是Box,像Result一样,只有在它包含的值可以进行相等比较时才能实现相等比较,而且error::Error不需要PartialEq (如果需要,那么error::Error无论如何都不会是对象安全的,因此您就不能使用dyn)。
也就是说,不能测试Err情况是否相等,因此Result的这个特定实例化也不能测试是否相等。编译器并不关心您正在检查一个Ok值,这意味着它永远不需要比较Err变量值,它只看到两个Result被比较为相等,并且找不到一个PartialEq实现。
要解决这个问题,您可以修改断言:
let expected = ParsingResult::new("Title", String::from("String"));
let actual = yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await;
assert_eq!(actual.ok(), Some(expected));.ok()方法将Result<V, E>映射为Option<V>,将Ok(v)映射到Some(v),将Err(_)映射到None。这有效地放弃了错误,从而绕过了错误类型具有相等比较实现的需要。
如果您希望保留错误信息,以便在测试失败时显示,请考虑将错误映射到具有相等操作的类型。例如,只需将错误映射到字符串化的调试表示。这将将Err变体转换为String,这显然提供了相等的比较。
let expected = ParsingResult::new("Title", String::from("String"));
let actual = yahoo_template("https://ro.wikipedia.org/wiki/Guy_de_Maupassant").await;
assert_eq!(actual.map_err(|e| format!("{:?}", e)), Ok(expected));https://stackoverflow.com/questions/72634784
复制相似问题