chore: Add ability to mock commands during tests (#768)

This commit is contained in:
Thomas O'Donnell 2020-01-11 16:08:32 +01:00 committed by Matan Kushner
parent fa6de4b769
commit 0d81694e32
1 changed files with 38 additions and 5 deletions

View File

@ -25,7 +25,29 @@ impl PartialEq for CommandOutput {
} }
/// Execute a command and return the output on stdout and stderr if sucessful /// Execute a command and return the output on stdout and stderr if sucessful
#[cfg(not(test))]
pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> { pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> {
internal_exec_cmd(&cmd, &args)
}
#[cfg(test)]
pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> {
let command = match args.len() {
0 => String::from(cmd),
_ => format!("{} {}", cmd, args.join(" ")),
};
match command.as_str() {
"dummy_command" => Some(CommandOutput {
stdout: String::from("stdout ok!"),
stderr: String::from("stderr ok!"),
}),
// If we don't have a mocked command fall back to executing the command
_ => internal_exec_cmd(&cmd, &args),
}
}
fn internal_exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> {
log::trace!("Executing command '{:?}' with args '{:?}'", cmd, args); log::trace!("Executing command '{:?}' with args '{:?}'", cmd, args);
match Command::new(cmd).args(args).output() { match Command::new(cmd).args(args).output() {
Ok(output) => { Ok(output) => {
@ -53,9 +75,20 @@ pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn exec_mocked_command() {
let result = exec_cmd("dummy_command", &[]);
let expected = Some(CommandOutput {
stdout: String::from("stdout ok!"),
stderr: String::from("stderr ok!"),
});
assert_eq!(result, expected)
}
#[test] #[test]
fn exec_no_output() { fn exec_no_output() {
let result = exec_cmd("true", &[]); let result = internal_exec_cmd("true", &[]);
let expected = Some(CommandOutput { let expected = Some(CommandOutput {
stdout: String::from(""), stdout: String::from(""),
stderr: String::from(""), stderr: String::from(""),
@ -66,7 +99,7 @@ mod tests {
#[test] #[test]
fn exec_with_output_stdout() { fn exec_with_output_stdout() {
let result = exec_cmd("/bin/echo", &["-n", "hello"]); let result = internal_exec_cmd("/bin/echo", &["-n", "hello"]);
let expected = Some(CommandOutput { let expected = Some(CommandOutput {
stdout: String::from("hello"), stdout: String::from("hello"),
stderr: String::from(""), stderr: String::from(""),
@ -77,7 +110,7 @@ mod tests {
#[test] #[test]
fn exec_with_output_stderr() { fn exec_with_output_stderr() {
let result = exec_cmd("/bin/sh", &["-c", "echo hello >&2"]); let result = internal_exec_cmd("/bin/sh", &["-c", "echo hello >&2"]);
let expected = Some(CommandOutput { let expected = Some(CommandOutput {
stdout: String::from(""), stdout: String::from(""),
stderr: String::from("hello\n"), stderr: String::from("hello\n"),
@ -88,7 +121,7 @@ mod tests {
#[test] #[test]
fn exec_with_output_both() { fn exec_with_output_both() {
let result = exec_cmd("/bin/sh", &["-c", "echo hello; echo world >&2"]); let result = internal_exec_cmd("/bin/sh", &["-c", "echo hello; echo world >&2"]);
let expected = Some(CommandOutput { let expected = Some(CommandOutput {
stdout: String::from("hello\n"), stdout: String::from("hello\n"),
stderr: String::from("world\n"), stderr: String::from("world\n"),
@ -99,7 +132,7 @@ mod tests {
#[test] #[test]
fn exec_with_non_zero_exit_code() { fn exec_with_non_zero_exit_code() {
let result = exec_cmd("false", &[]); let result = internal_exec_cmd("false", &[]);
let expected = None; let expected = None;
assert_eq!(result, expected) assert_eq!(result, expected)