创建一个`std :: env :: Args`迭代器进行测试

Che*_*evy 10 unit-testing parameter-passing rust

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

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

我无法从文档,来源或谷歌搜索中找到这个.

Sch*_*ern 9

这些字段std::env::Args没有记录,并且似乎没有公共功能来创建具有自定义字段的字段.所以,你在那里运气不好.

但是因为它只是" 一个进程参数的迭代器,String为每个参数产生一个值 ",所以你的函数可以使用String迭代器,也可以Vec不丢失任何功能或类型安全性.由于它只是一个Strings 列表,因此任意将函数限制为恰好来自命令行的字符串没有多大意义.

通过Rust自己的测试,这正是他们所做的.有很多let args: Vec<String> = env::args().collect();

甚至有一个例子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();
}
Run Code Online (Sandbox Code Playgroud)

而bootstrap::Config::parse()看起来像这样:

impl Config {
    pub fn parse(args: &[String]) -> Config {
        let flags = Flags::parse(&args);
        ...
Run Code Online (Sandbox Code Playgroud)

我不是Rust专家,但这似乎是Rust人员如何处理这个问题.


小智 6

@Schwern 的答案很好,它让我找到了这个更简单的版本。由于您可以执行以下操作std::env::Args:IteratorItem = 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());
}
Run Code Online (Sandbox Code Playgroud)

为了进行测试,您提供了parse一个迭代器String:

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