创建一个用于测试的std :: env :: Args`迭代器

问题描述 投票:12回答:3

Rust中是否有一种方法可以从std::env::Args创建一个Vec<String>以便在#[test]函数中使用它?

我希望测试一个以std::env::Args作为参数的函数,但是我不知道如何使用我为测试提供的参数列表来创建这样的对象。

我无法从文档,来源或Google搜索中找出这一点。

unit-testing rust parameter-passing
3个回答
9
投票

std::env::Args的字段未记录,并且似乎没有公共功能来创建带有自定义字段的功能。因此,您在那里没有运气。

但是因为它只是“ 一个过程的参数的迭代器,为每个参数产生一个std::env::Args”,您的函数可以使用String迭代器或String,而不会损失任何功能或类型安全。因为它只是Vec的列表,所以将函数任意地限制为恰好来自命令行的字符串并没有多大意义。

浏览String,这就是他们所做的。有很多Rust's own tests

甚至在let args: Vec<String> = env::args().collect();中,它们都删除了程序的名称,只提供了参数列表。

an example in rustbuild

[rustbuild看起来像这样:

use std::env;

use bootstrap::{Config, Build};

fn main() {
    let args = env::args().skip(1).collect::<Vec<_>>();
    let config = Config::parse(&args);
    Build::new(config).build();
}

我不是Rust专家,但这似乎是Rust员工处理问题的方式。


3
投票

bootstrap::Config::parse()很好,它使我想到了这个简单的版本。由于bootstrap::Config::parse()impl Config { pub fn parse(args: &[String]) -> Config { let flags = Flags::parse(&args); ... 实现了@Schwern's answer,因此您可以这样做:

std::env::Args

要进行测试,请为Iterator提供一个在Item = String之上的迭代器:

use std::env;

fn parse<T>(args: T)
where
    T: Iterator<Item = String>,
{
    for arg in args {
        // arg: String
        print!("{}", arg);
    }
}

fn main() {
    parse(env::args());
}

0
投票

[基于parse,我也写了一个小宏使它变得更容易(因此也基于String;感谢两者都:)]

#[test]
fn test_parse() {
   let args = ["arg1", "arg2"].iter().map(|s| s.to_string());
   parse(args);
}

可以以这种方式使用:

@Rossman's answer

或在@Schwern's answer上尝试。

我还不是防锈专家,非常欢迎您提出任何建议:)

© www.soinside.com 2019 - 2024. All rights reserved.