Crate mockcmd

Source
Expand description

§mockcmd

A lightweight mocking library for command execution in Rust.

This crate provides a drop-in replacement for std::process::Command with added mocking capabilities for tests. It offers a clean, ergonomic API for mocking command execution while maintaining the same interface as the standard library.

§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

§Usage Example

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 is a drop-in replacement for std::process::Command that uses conditional compilation to provide different implementations depending on whether you’re in a test context:

  • 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:

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:

- 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.

Structs§

Command
CommandMockBuilder
ExecutedCommand
A record of an executed command.
MockDefinition
Represents a definition for how a command should be mocked.

Functions§

find_mock
get_executed_commands
Returns a copy of all executed commands.
mock
Creates a new command mock builder for the specified program.
was_command_executed
Panics if pieces is empty.