MST
星途 面试题库

面试题:Rust中如何编写并测试一个异步函数

编写一个Rust异步函数,它接收两个URL作为参数,异步地获取这两个URL对应的网页内容,并返回内容长度较长的那个网页内容。同时编写相应的测试,包括单元测试和集成测试,确保函数在不同情况下的正确性,要考虑网络错误等异常情况的处理。
11.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
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(())
    }
}

代码说明

  1. fetch_url函数:使用reqwest库异步获取给定URL的网页内容。
  2. get_longest_content函数:调用fetch_url获取两个URL的内容,并返回长度较长的那个。
  3. 单元测试
    • test_get_longest_content:使用mockito库模拟两个URL的响应,测试函数能否正确返回较长的内容。
    • test_get_longest_content_network_error:模拟一个有效的URL和一个无效的URL,测试函数在网络错误时是否返回错误。