VOOZH about

URL: https://deepwiki.com/MahoCommerce/maho-phpstan-plugin/6-mock-framework

⇱ Mock Framework | MahoCommerce/maho-phpstan-plugin | DeepWiki


Loading...
Menu

Mock Framework

The Mock Framework provides stub class definitions that give PHPStan type information about Maho/Magento core classes without requiring a full Maho installation. These lightweight mock files define class structures, method signatures, and return types that PHPStan uses during static analysis.

For information about how these types are dynamically resolved during analysis, see Type Inference System. For details on specific mock implementations, see Maho Core Mocks and Laminas Framework Mocks.

Purpose and Architecture

Why Mocks Are Needed

PHPStan requires access to class definitions to perform type checking. However, the maho-phpstan-plugin is a standalone package that cannot depend on the entire Maho/Magento framework. Installing all of Maho just to provide type information would be impractical and would create circular dependencies.

The mock framework solves this by providing minimal stub definitions that contain only the information PHPStan needs:

  • Class declarations
  • Method signatures with proper type hints
  • Return type declarations
  • Interface implementations
  • Constant definitions

These mocks do not contain actual implementation logic—they exist solely to provide structural and type information.

Sources: extension.neon9-11

Mock Loading Configuration


The scanDirectories parameter in extension.neon9-11 instructs PHPStan to include mock directories in its autoloader:


This makes all mock classes available during analysis without requiring them to be explicitly imported.

Sources: extension.neon9-11

Mock Directory Structure

The mock framework is organized into separate directories based on the source of the classes being mocked:

DirectoryPurposeContains
mock/maho-phpstan-plugin/Plugin-specific stubsMage.php, DataObject.php
mock/maho/Core Maho framework classesFull Maho class hierarchy stubs
mock/laminas/ (implied)Laminas framework dependenciesSOAP, XML-RPC, JSON-RPC server stubs

This separation allows the plugin to mock only the necessary external dependencies while keeping the plugin's own repository lightweight.

Sources: extension.neon9-11

Core Mock Components

Mage Static Class Mock

The Mage class is the central hub in Maho/Magento architecture. The mock definition provides type information for its static factory methods and initialization functions.


Key Components in mock/maho-phpstan-plugin/Mage.php:

BP Constant mock/maho-phpstan-plugin/Mage.php6

  • Defines the base path constant used throughout Maho
  • Set as empty string in mock (actual value determined at runtime)

Mage Class mock/maho-phpstan-plugin/Mage.php11-30

  • Declared as final class matching actual implementation
  • Provides signatures for static factory methods
  • app() method returns Mage_Core_Model_App with proper type hints
  • init() method signature includes parameter types for options arrays

Mage_Core_Model_App mock/maho-phpstan-plugin/Mage.php35-45

  • Application model that provides access to core services
  • getConfig() returns Mage_Core_Model_Config

Mage_Core_Model_Config mock/maho-phpstan-plugin/Mage.php50-105

  • Configuration model with class name resolution methods
  • Methods like getModelClassName(), getBlockClassName(), getHelperClassName()
  • Return types specified as string or string|false for error cases
  • These methods are used by MageCoreConfig to resolve class aliases (see MageCoreConfig)

Varien_Object mock/maho-phpstan-plugin/Mage.php111-118

  • Legacy base class for data objects
  • Implements ArrayAccess<string, mixed> and JsonSerializable
  • Provides type hints for array access methods
  • Used by VarienObjectReflectionExtension for magic method support (see Magic Method Support)

Sources: mock/maho-phpstan-plugin/Mage.php1-119

Configuration Class Method Signatures

The Mage_Core_Model_Config mock includes several critical class name resolution methods that mirror the actual Maho API:

MethodParameterReturn TypePurpose
getNodeClassName()string $pathstringResolves class from XML path
getBlockClassName()string $blockTypestringResolves block alias to class name
getHelperClassName()string $helperAliasstringResolves helper alias to class name
getModelClassName()string $modelAliasstringResolves model alias to class name
getResourceModelClassName()string $modelAliasstring|falseResolves resource model, returns false on error
getResourceHelperClassName()string $moduleAliasstring|falseResolves resource helper, returns false on error

These signatures allow PHPStan to understand the contract of these methods, which is essential for the type inference system. The MageCoreConfig class (see MageCoreConfig) uses these same method names when it implements the actual resolution logic.

Sources: mock/maho-phpstan-plugin/Mage.php50-105

DataObject Mock

The Maho\DataObject class is the modern, namespaced replacement for Varien_Object. Both classes provide the same array-like interface for data manipulation.


Mock Definition mock/maho-phpstan-plugin/DataObject.php9-16

  • Namespaced as Maho\DataObject
  • Generic type parameters: ArrayAccess<string, mixed>
  • All interface methods declared with proper signatures
  • Empty method bodies (implementation not needed for static analysis)

The mock provides identical interface implementations for both Varien_Object and Maho\DataObject, ensuring consistent type checking regardless of which base class is used in the codebase.

Sources: mock/maho-phpstan-plugin/DataObject.php1-17

Interface Implementations

Both Varien_Object and Maho\DataObject implement the same interfaces with identical signatures:

ArrayAccess Interface

The ArrayAccess interface allows objects to be accessed like arrays. The mock specifies the generic type ArrayAccess<string, mixed>, indicating that:

  • Array keys must be strings
  • Array values can be any type

This typing information helps PHPStan understand expressions like:


JsonSerializable Interface

The JsonSerializable interface allows objects to specify how they should be encoded to JSON. The mock declares:


This ensures PHPStan understands that these objects can be safely passed to json_encode().

Sources: mock/maho-phpstan-plugin/Mage.php111-118 mock/maho-phpstan-plugin/DataObject.php9-16

Integration with Type Extensions

The mock framework works in concert with the plugin's type extension system:


Key Interactions:

  1. Type Extension Dependencies: MageTypeExtension (see MageTypeExtension) needs the Mage class definition to identify which methods to intercept. The mock provides this structure.

  2. Configuration Method Signatures: MageCoreConfig (see MageCoreConfig) implements its own versions of methods like getModelClassName(), but the mock's signatures ensure type consistency.

  3. Reflection Base Classes: VarienObjectReflectionExtension (see Magic Method Support) operates on classes that extend Varien_Object or Maho\DataObject. The mocks define these base classes.

Sources: extension.neon13-70 mock/maho-phpstan-plugin/Mage.php1-119 mock/maho-phpstan-plugin/DataObject.php1-17

Mock Limitations and Design

What Mocks Include

  • Class declarations and inheritance hierarchies
  • Method signatures with parameter types
  • Return type declarations
  • Interface implementations
  • Constants that affect type checking

What Mocks Exclude

  • Method implementations (always empty bodies)
  • Property values (no default values needed)
  • Documentation comments (PHPDoc only where needed for types)
  • Private/protected members that don't affect public API
  • Business logic or runtime behavior

This minimalist approach keeps the mock framework lightweight while providing all information PHPStan requires for accurate type analysis.

Sources: mock/maho-phpstan-plugin/Mage.php1-119 mock/maho-phpstan-plugin/DataObject.php1-17

Extension and Maintenance

Adding New Mocks

To add mocks for additional classes:

  1. Identify which classes PHPStan cannot resolve
  2. Create stub files in the appropriate mock directory
  3. Include only public API signatures
  4. Ensure return types match actual Maho behavior
  5. Verify scanDirectories includes the mock location

Versioning Considerations

Mocks must stay synchronized with the Maho version being analyzed. When Maho adds new methods or changes signatures, corresponding mocks should be updated. However, because mocks only define structures, they can often work across multiple Maho versions if the core API remains stable.

Sources: extension.neon9-11