VOOZH about

URL: https://deepwiki.com/hypervel/foundation/6.8-console-command-testing

⇱ Console Command Testing | hypervel/foundation | DeepWiki


Loading...
Last indexed: 7 February 2026 (101eff)
Menu

Console Command Testing

Purpose and Scope

This document covers the console command testing infrastructure in Hypervel Foundation. It explains how to write tests that execute console commands, verify their output, mock interactive input, and assert their exit codes. The testing system provides a fluent API for defining expectations about command behavior before execution.

For information about the Console Kernel and command registration, see Console Kernel and Command Execution. For general testing foundation and lifecycle, see Test Case Foundation and Lifecycle.


Overview of Console Command Testing

Console command testing in Hypervel Foundation follows a declarative, expectation-based approach. Tests define what output and interactions they expect before the command executes, then the framework verifies these expectations automatically.

Testing Architecture


Architecture Diagram: Console Testing Components

Sources: src/Testing/Concerns/InteractsWithConsole.php1-89 src/Testing/PendingCommand.php1-573


The InteractsWithConsole Trait

The InteractsWithConsole trait provides the entry point for console command testing. Test classes that use this trait gain the ability to execute commands and set up output mocking.

Key Properties

PropertyTypePurpose
$mockConsoleOutputboolControls whether console output should be mocked (default: true)
$expectsOutput?boolIndicates if any output is expected (true), none expected (false), or unspecified (null)
$expectedOutputarrayExact output lines expected to be printed
$expectedOutputSubstringsarrayText that must appear somewhere in output
$unexpectedOutputarrayOutput lines that should not be printed
$unexpectedOutputSubstringsarrayText that should not appear in output
$expectedQuestionsarrayQuestions that should be asked with their answers
$expectedChoicesarrayChoice questions with available options

Command Execution Methods

command(string $command, array $parameters = [])

Executes a console command. When $mockConsoleOutput is true, returns a PendingCommand instance for fluent expectation setting. When false, executes immediately and returns the exit code.

artisan(string $command, array $parameters = [])

Alias for command() method, providing familiar Laravel-style naming.

withoutMockingConsoleOutput()

Disables output mocking for subsequent commands, causing them to execute immediately without expectation verification.

Sources: src/Testing/Concerns/InteractsWithConsole.php10-88


The PendingCommand Class

PendingCommand is the core class that builds and verifies command execution expectations. It uses a fluent interface pattern where expectation methods return $this for chaining. The command executes automatically when the object is destroyed if not already executed explicitly.

Class Structure


Class Diagram: PendingCommand Structure

Sources: src/Testing/PendingCommand.php30-65


Setting Output Expectations

Output expectations define what text should or should not appear when the command executes. The framework uses Mockery to mock BufferedOutput and verify write operations.

Exact Output Matching

expectsOutput(?string $output = null)

Expects an exact output line to be printed. If called with no argument, it sets a flag that any output is expected. Multiple calls add multiple expected lines that must appear in order.


doesntExpectOutput(?string $output = null)

Asserts that specific output should not be printed. If called with no argument, it asserts that no output should be printed at all.

Sources: src/Testing/PendingCommand.php109-138

Substring Matching

expectsOutputToContain(string $string)

Expects output to contain the given substring anywhere. Unlike expectsOutput(), this doesn't require exact matching or ordering.

doesntExpectOutputToContain(string $string)

Asserts that output should not contain the given substring anywhere.

Sources: src/Testing/PendingCommand.php140-158

Table Output

expectsTable(array $headers, array|Arrayable $rows, string $tableStyle = 'default', array $columnStyles = [])

Expects a formatted table to be rendered. This method internally renders the table using Symfony's Table class and adds each line as an expected output.


Sources: src/Testing/PendingCommand.php160-185

Prompts Output

The framework provides specialized expectations for Laravel Prompts-style output:

MethodPurpose
expectsPromptsInfo(string $message)Expects an info-level prompt note
expectsPromptsWarning(string $message)Expects a warning-level prompt note
expectsPromptsError(string $message)Expects an error-level prompt note
expectsPromptsAlert(string $message)Expects an alert-level prompt note
expectsPromptsIntro(string $message)Expects an intro-level prompt note
expectsPromptsOutro(string $message)Expects an outro-level prompt note
`expectsPromptsTable(arrayCollection $headers, array

These methods render the prompt component to a BufferedOutput and expect the resulting text in the command output.

Sources: src/Testing/PendingCommand.php187-287


Testing Interactive Input

Interactive commands that ask questions can be tested by pre-defining the answers the user would provide.

Question Expectations

expectsQuestion(string $question, bool|string $answer)

Expects a question to be asked and provides the answer. Questions are matched in order and must appear exactly as specified.


Sources: src/Testing/PendingCommand.php67-75

Confirmation Expectations

expectsConfirmation(string $question, string $answer = 'no')

Convenience method for yes/no questions. Converts the answer to a boolean ('yes'true, anything else → false).


Sources: src/Testing/PendingCommand.php77-83

Choice Expectations

expectsChoice(string $question, array|string $answer, array $answers, bool $strict = false)

Expects a choice question with multiple options. The $answers parameter defines the available choices, and the test verifies these match what the command actually presents.


When $strict is true, the order of choices must match exactly. Otherwise, only the presence of choices is verified.

Sources: src/Testing/PendingCommand.php85-96

Search Expectations

expectsSearch(string $question, array|string $answer, string $search, array $answers)

Expects a search-style question where the user first types a search query, then selects from filtered results. This combines expectsQuestion() for the search input with expectsChoice() for the selection.


Sources: src/Testing/PendingCommand.php98-106


Asserting Exit Codes

Exit code assertions define the expected success or failure state of the command.

Exit Code Methods

assertExitCode(int $exitCode)

Asserts the command exits with a specific code.

assertNotExitCode(int $exitCode)

Asserts the command does not exit with a specific code.

assertSuccessful() / assertOk()

Convenience methods that assert the command exits with Command::SUCCESS (0).

assertFailed()

Asserts the command does not exit with Command::SUCCESS.


Sources: src/Testing/PendingCommand.php289-331


Command Execution and Verification Flow

The execution flow involves multiple stages: setup, mocking, execution, verification, and cleanup.

Execution Sequence


Sequence Diagram: Command Execution and Verification

Sources: src/Testing/PendingCommand.php336-394 src/Testing/PendingCommand.php399-433

Mockery Integration Details

The PendingCommand class creates sophisticated Mockery mocks to intercept console I/O:

SymfonyStyle Mock

Created at src/Testing/PendingCommand.php437-469 Mocks the askQuestion() method to:

  • Match questions by their text content
  • Return pre-defined answers from $expectedQuestions
  • Capture choice options from ChoiceQuestion instances
  • Verify questions are asked in order
  • Remove questions from the expectations array as they're asked

BufferedOutput Mock

Created at src/Testing/PendingCommand.php476-545 Mocks the doWrite() method to:

  • Match exact output strings when set via expectsOutput()
  • Match substring presence when set via expectsOutputToContain()
  • Detect unexpected output when set via doesntExpectOutput()
  • Track which expectations have been fulfilled
  • Remove fulfilled expectations from the arrays

Verification Process

The verifyExpectations() method src/Testing/PendingCommand.php399-432 checks that all expectations were met:

  1. Unfulfilled Questions: If any questions remain in $expectedQuestions, the test fails with a message identifying the first unanswered question
  2. Choice Option Matching: For choice questions, verifies the actual options presented match the expected options (strictly ordered or canonically equivalent)
  3. Unfulfilled Output: If any output remains in $expectedOutput or $expectedOutputSubstrings, the test fails
  4. Unexpected Output Detection: If $unexpectedOutput or $unexpectedOutputSubstrings were flagged as true (meaning they appeared), the test fails

Automatic Execution

PendingCommand implements a destructor src/Testing/PendingCommand.php564-571 that automatically calls run() if the command hasn't been executed yet. This allows for a more natural testing style:


Sources: src/Testing/PendingCommand.php336-394 src/Testing/PendingCommand.php399-432 src/Testing/PendingCommand.php437-545 src/Testing/PendingCommand.php564-571


Exception Handling During Command Execution

The execution flow includes special handling for command failures. When a command throws an exception, it's captured through the event dispatcher:


Flow Diagram: Exception Handling

The framework listens for FailToHandle events src/Testing/PendingCommand.php353-356 and stores any exceptions. After the command completes, if an exception occurred, it's re-thrown src/Testing/PendingCommand.php370-372 This ensures that command failures are properly propagated to the test.

Sources: src/Testing/PendingCommand.php346-394


Integration with Database Testing

Console command tests frequently need to interact with the database. The RefreshDatabase trait can be used alongside console testing to ensure a clean database state.

When testing commands that run migrations, special handling is required. The RefreshDatabase trait temporarily disables console output mocking src/Testing/RefreshDatabase.php75-93 when running migrate:fresh to avoid interfering with the test's own migration needs.

For tests that execute migration commands directly:


Sources: src/Testing/RefreshDatabase.php73-96


Mock Control and Direct Execution

By default, InteractsWithConsole enables output mocking. This can be disabled when you need to see actual command output or test real console interactions.

withoutMockingConsoleOutput()

Disables mocking for the test instance. Subsequent calls to command() will execute immediately and return the exit code integer instead of a PendingCommand instance.


The $mockConsoleOutput property src/Testing/Concerns/InteractsWithConsole.php15 controls this behavior and can also be set directly:


Sources: src/Testing/Concerns/InteractsWithConsole.php82-87 src/Testing/Concerns/InteractsWithConsole.php68-77


Testing Patterns and Examples

Testing Command Output


Testing Interactive Commands


Testing Failed Commands


Testing Commands Without Expectations


Sources: src/Testing/PendingCommand.php1-573 src/Testing/Concerns/InteractsWithConsole.php1-89

Refresh this wiki

On this page