# `mockcmd` An ergonomic drop-in replacement for `std::process::Command` with added mocking capabilities for tests. > âš ï¸ **Warning**: This crate is still in early development. The API will change significantly in future releases. ## Key Features - Direct replacement for `std::process::Command` with identical API - Mock command execution with specific arguments - Set custom exit codes, stdout, and stderr - Verify command execution happened with specific arguments - Automatically disabled outside of test mode (zero overhead in production) ## Installation Add this to your `Cargo.toml`: ```toml [dependencies] mockcmd = "*" [dev-dependencies] mockcmd = { version = "*", features = ["test"] } ``` ## Usage Example ```rust use mockcmd::{Command, mock, was_command_executed}; // Setup a mock for the "git" command mock("git") .with_arg("status") .with_stdout("On branch main\nNothing to commit") .register(); // Use the Command just like std::process::Command let output = Command::new("git").arg("status").output().unwrap(); // The mock is used instead of executing the real command assert_eq!(String::from_utf8_lossy(&output.stdout), "On branch main\nNothing to commit"); // Verify that the command was executed with the correct arguments assert!(was_command_executed(&["git", "status"])); assert!(!was_command_executed(&["git", "push"])); ``` ## How It Works The library uses conditional compilation to provide different implementations: - In test mode (`#[cfg(feature = "test")]`), commands are intercepted and mocked responses are returned - In normal mode, commands pass through to the standard library's process module with zero overhead This means your production code can use the same `Command` interface without any behavior changes or performance impact. ## Setting Up Mocks Mocks are defined using a builder pattern, which allows for a fluent API: ```rust use mockcmd::mock; // Create a simple mock mock("program") .with_arg("arg1") .with_arg("arg2") .with_stdout("Success output") .with_stderr("Error message") .with_status(0) // Exit code .register(); ``` ## Migrating from std::process::Command Migration is as simple as changing your import statement: ```diff - use std::process::Command; + use mockcmd::Command; ``` Your existing code will continue to work exactly as before, but now you can add mocks in your tests.