Testing Reqwest';s客户机::新的挂起测试在第二个线程中使用Iron

Testing Reqwest';s客户机::新的挂起测试在第二个线程中使用Iron,testing,rust,iron,reqwest,Testing,Rust,Iron,Reqwest,我在我的网络爬虫程序中使用Reqwest,我试图为主循环添加测试,以确保获得正确的输出。我正试图使用Iron作为假HTTP服务器,并带有预设响应。但是,在我的main_循环函数中,let client=client::new()挂起 主循环的前几行: fn _main_loop(starton: String, panic: bool) { //panic("test") // calls as normal let client = Client::new(); // <

我在我的网络爬虫程序中使用Reqwest,我试图为主循环添加测试,以确保获得正确的输出。我正试图使用Iron作为假HTTP服务器,并带有预设响应。但是,在我的
main_循环
函数中,
let client=client::new()挂起

主循环的前几行:

fn _main_loop(starton: String, panic: bool) {
    //panic("test") // calls as normal
    let client = Client::new(); // <-- problem!
    panic("test") // doesn't call
    let mut future_urls: Vec<String>;
    // ...
}
终端输出:

$cargo测试
编译爬虫v1.0.0(file:///home/*******/爬虫机)
警告:无法访问的语句
-->src/main.rs:82:5
|
82 |让mut future_url:Vec;
|     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
=注意:#[警告(无法访问的_代码)]默认打开
警告:未使用的变量:`client`
-->src/main.rs:80:9
|
80 |让client=client::new();
帮助:考虑使用“客户端”代替
|
=注意:#[警告(未使用的_变量)]默认打开
警告:未使用的变量:`starton`
-->src/main.rs:79:15
|
79 | fn _main _loop(starton:String,_panic:bool)->Vec{
帮助:考虑使用'Stalt'代替
警告:未使用的变量:`child`
-->src/main.rs:239:13
|
239 | let child=std::thread::spawn(| Iron::new(Chain::new(handler)).http(“localhost:9999”).unwrap();
帮助:考虑使用“孩子”代替
在4.24秒内完成开发[未优化+调试信息]目标
正在运行target/debug/deps/crawler-9c5de394eb85849d
运行9个测试
测试html::测试::获取元素的属性…确定
测试html::测试::\uHTML\uToken\uSink…确定
测试url\u utils::测试::\u添加\u url\u到\u vec…确定
测试url_utils::tests::_get_root_domain…确定
测试html::测试::在html中查找URL…确定
测试url\u实用程序::测试::\u检查\u是否在\u url\u列表中…确定
测试url_utils::tests::_remove_get_params…确定
测试url\u实用程序::测试::\u修复\u建议的\u url…确定

当运行测试单线程(
--test threads 1
)时,它以
测试结束::\uu main\u loop…

我认为问题在于您生成的线程没有终止,测试最终等待它终止(我不确定为什么会发生这种情况,并且它不会在一段时间后被测试运行者杀死),即问题不是reqwest,而是您的iron服务器

现在我不知道如何解决这个问题,事实上,iron 0.6.0似乎已经崩溃了,因为iron 0.6.0仍然依赖于不再具有该功能的hyper 0.10

在最坏的情况下,您可以直接使用hyper实现服务器,就像我所做的那样。也许您的原始代码有一个实际的快速解决方案,我不知道

通常,如果你能在测试中找到运行服务器的方法,我认为这是一个理想的情况。对于我之前链接的板条箱(
reqwest mock
,免责声明我是作者)您可以编写
\u main\u loop
函数,以a作为参数,然后在测试中使用模拟请求,并在生产代码中使用直接客户端。但是,您甚至不需要这样做,应该以设计爬虫程序为目标,以便尽可能独立地测试不同的函数

#[cfg(test)]
mod tests {
    use iron::{Iron, IronResult, Headers};
    use iron::response::Response;
    use iron::request::Request;
    use iron::status;
    use iron::middleware::Chain;
    use iron::headers::ContentType;
    use iron::mime::{Mime, TopLevel, SubLevel};
    use iron::typemap::TypeMap;
    use std;

    use *;

    #[test]
    fn __main_loop() {
        fn handler(req: &mut Request) -> IronResult<Response> {
            let mut mime = Headers::new();
            mime.set(ContentType(Mime(TopLevel::Text, SubLevel::Html, Vec::new())));

            Ok(Response {
                headers: mime,
                status: Some(status::Ok),
                body: Some(Box::new(match req.url.path().join("/").as_str() {
                "" => "<a href='file'></a><a href='file1'></a>",
                "file" => "<a href='/file1'></a>",
                "file1" => "<a href='/file'></a>",
                _ => "not found"
                })),
                extensions: TypeMap::new()
            })
        }

        let child = std::thread::spawn(|| Iron::new(Chain::new(handler)).http("localhost:9999").unwrap());

        let f: Vec<String> = Vec::new();
        assert_eq!(_main_loop("http://localhost:9999/".to_string(), false), f);
    }
}