Introduction
The Sandbox package includesFakeSandbox, a test double that implements the same CanExecuteCommand interface as all real drivers. It lets you write fast, deterministic tests for code that depends on sandbox execution — without spawning any processes, pulling container images, or requiring any system binaries.
FakeSandbox supports canned responses, FIFO queuing for repeated commands, a default fallback response, array-based response definitions, command recording, streaming callback simulation, and custom policies.
Creating a Fake
The fromResponses() Factory
The quickest way to create a mock is with the fromResponses() static factory. Pass an associative array where keys are the expected command strings and values are lists of ExecResult objects to return in order:
['php', '-v'] becomes 'php -v'. Make sure the key in your response map matches exactly.
The Constructor
For more control, use the constructor directly. This lets you specify a customExecutionPolicy:
fromResponses() factory uses ExecutionPolicy::default() when no policy is specified.
Queueing Multiple Responses
When the same command is called multiple times, provide multiple results in the list. They are consumed in FIFO order — each call toexecute() shifts the next response off the queue:
RuntimeException.
Default Response
To provide a fallback for any command that does not have a specific canned response, pass adefaultResponse:
Enqueuing Responses After Construction
You can add responses to an existing fake at any time using theenqueue() method. This is useful in test setups where you build the fake incrementally:
Array-Based Responses
For convenience, you can define responses as associative arrays instead ofExecResult objects. The mock normalizes them automatically:
ExecResult::toArray() format:
| Key | Type | Default |
|---|---|---|
stdout | string | '' |
stderr | string | '' |
exit_code | int | 0 |
duration | float | 0.0 |
timed_out | bool | false |
truncated_stdout | bool | false |
truncated_stderr | bool | false |
Inspecting Recorded Commands
The mock records every command it receives. Use thecommands() method to retrieve the full history:
Standard Input Recording
When stdin is provided, it is appended to the recorded argv as a[stdin=...] entry:
Streaming Callback Support
TheFakeSandbox honors the streaming callback, just like real drivers. When a callback is provided, the fake delivers stdout and stderr from the canned response as single chunks:
Testing Failure Scenarios
Simulating Timeouts
Create anExecResult with timedOut: true and exit code 124:
Simulating Truncated Output
Set the truncation flags to test how your code handles oversized output:Simulating Command Failures
Test error handling by returning non-zero exit codes:Using FakeSandbox with Dependency Injection
TheFakeSandbox implements CanExecuteCommand, so it can be injected anywhere a real sandbox is expected. This is the recommended approach for testing application services:
Quick Reference
| Method | Purpose |
|---|---|
FakeSandbox::fromResponses($responses, $defaultResponse) | Create fake with canned responses and optional default |
new FakeSandbox($policy, $responses, $defaultResponse) | Create fake with custom policy |
$mock->enqueue($key, $result) | Add a response to the queue after construction |
$mock->execute($argv, $stdin, $onOutput) | Execute and return next canned response |
$mock->commands() | Get all recorded commands as list<list<string>> |
$mock->policy() | Access the execution policy |