0

I'm writing a Rust program where I do manual command-line argument parsing. I skip the first argument since that's the executable and I don't care about that, then check the second argument for what subcommand to run. Then I pass on the rest of env::Args to that subcommand's function for parsing of the subcommand arguments.

Now, I want to add some tests that test the entire subcommands to see if they do what's expected of them—a bit like integration tests except within the codebase. However, I can't find any way to construct my own env::Args. Is this something that's possible? I had a look at a similar question about replacing an entry in env::Args but it seems that's impossible.

Is there any way I can achieve what I want, i.e. testing of my subcommand functions that take an env::Args by providing a forged one?

1
  • 1
    No. But you can easily give the command a Vec. Commented Nov 10 at 11:09

1 Answer 1

2

I ended up solving this by changing the signature of the subcommands from directly taking an env::Args

fn cmd_something(arguments: env::Args) -> ExitCode { ... }

to taking any type that implements IntoIterator where the item type is String:

fn cmd_something<I: IntoIterator<Item = String>>(arguments: I) -> ExitCode { ... }

This allows me to both call the function with env::Args and arrays or Vecs, so that in tests I can do something like this:

let arguments = ["testdata/testfile.txt".to_string()];

assert_eq!(cmd_something(arguments), ExitCode::SUCCESS);

Which is very convenient. This works because both std::Env and Vec implement the IntoIterator trait.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.