use std::io::{self, Read};
use std::error::Error;
use reqwest::Error as ReqwestError;
use futures::{FutureExt, TryFutureExt};
async fn fetch_url(url: &str) -> Result<String, ReqwestError> {
let mut response = reqwest::get(url).await?;
let mut body = String::new();
response.read_to_string(&mut body).await?;
Ok(body)
}
async fn get_longest_content(url1: &str, url2: &str) -> Result<String, Box<dyn Error>> {
let content1 = fetch_url(url1).await.map_err(Box::from)?;
let content2 = fetch_url(url2).await.map_err(Box::from)?;
if content1.len() >= content2.len() {
Ok(content1)
} else {
Ok(content2)
}
}
#[cfg(test)]
mod tests {
use super::*;
use mockito::{mock, Matcher};
#[tokio::test]
async fn test_get_longest_content() -> Result<(), Box<dyn Error>> {
let mock1 = mock("GET", Matcher::Any)
.with_status(200)
.with_body("longer content")
.create();
let mock2 = mock("GET", Matcher::Any)
.with_status(200)
.with_body("short")
.create();
let result = get_longest_content(mock1.url(), mock2.url()).await?;
assert_eq!(result, "longer content");
Ok(())
}
#[tokio::test]
async fn test_get_longest_content_network_error() -> Result<(), Box<dyn Error>> {
let mock1 = mock("GET", Matcher::Any)
.with_status(200)
.with_body("content")
.create();
let bad_url = "http://nonexistenturl1234567890.com";
let result = get_longest_content(mock1.url(), bad_url).await;
assert!(result.is_err());
Ok(())
}
}
代码说明
fetch_url
函数:使用reqwest
库异步获取给定URL的网页内容。
get_longest_content
函数:调用fetch_url
获取两个URL的内容,并返回长度较长的那个。
- 单元测试:
test_get_longest_content
:使用mockito
库模拟两个URL的响应,测试函数能否正确返回较长的内容。
test_get_longest_content_network_error
:模拟一个有效的URL和一个无效的URL,测试函数在网络错误时是否返回错误。