Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mockista Laravel Package

janmarek/mockista

Mockista is a lightweight mocking library for PHP/Laravel that helps you create and configure test doubles quickly. Define expectations, stub methods, and verify calls with a simple, fluent API to keep unit tests fast, readable, and maintainable.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:
    composer require janmarek/mockista --dev
    
  2. Basic Usage: Replace PHPUnit’s getMockBuilder() with Mockista’s fluent interface:
    use Mockista\Mockista;
    
    $mock = Mockista::mock(UserRepository::class)
        ->method('find')
        ->returns($user);
    
  3. First Use Case: Mock a service dependency in a unit test:
    public function test_user_service_returns_correct_user()
    {
        $mockRepo = Mockista::mock(UserRepository::class)
            ->when('find', 1)
            ->thenReturn(new User());
    
        $service = new UserService($mockRepo);
        $user = $service->getUser(1);
    
        $this->assertInstanceOf(User::class, $user);
    }
    

Where to Look First

  • Mockista Documentation: Focus on the Quick Start and API Reference sections.
  • Migration Guide: Compare getMockBuilder() patterns with Mockista’s equivalents.
  • Laravel-Specific: Check the #12 issue for partial mocking workarounds.

Implementation Patterns

Core Workflows

1. Basic Mocking

// Replace:
$mock = $this->getMockBuilder(Service::class)
    ->disableOriginalConstructor()
    ->onlyMethods(['fetch'])
    ->getMock();

// With:
$mock = Mockista::mock(Service::class)
    ->method('fetch')
    ->returns($data);

2. Method Chaining with Conditions

$mock = Mockista::mock(OrderService::class)
    ->when('calculateTotal', [10, 2]) // Method + args
    ->thenReturn(20.00)
    ->when('applyDiscount', [20.00, '10%'])
    ->thenReturn(18.00);

3. Throwing Exceptions

$mock = Mockista::mock(Database::class)
    ->when('query')
    ->thenThrow(new RuntimeException('DB down'));

4. Partial Mocking (Laravel Workaround)

// Mock only specific methods in a class
$mock = Mockista::mock(User::class)
    ->partialMock()
    ->when('save')
    ->thenReturn(true);

5. Callback-Based Responses

$mock = Mockista::mock(Logger::class)
    ->when('log')
    ->thenCallback(function ($level, $message) {
        return "[$level] $message";
    });

Laravel Integration Tips

1. Mocking Facades

Use Mockista with Laravel’s MockFacade:

$mock = Mockista::mock(Auth::class)
    ->method('check')
    ->returns(true);

2. Service Container Bindings

For container-bound services, bind the mock directly:

$this->app->instance(
    UserRepository::class,
    Mockista::mock(UserRepository::class)
        ->when('find', 1)
        ->thenReturn(new User())
);

3. Eloquent Model Mocks

Create a mock interface and adapter:

interface UserRepositoryInterface {
    public function find(int $id);
}

$mock = Mockista::mock(UserRepositoryInterface::class)
    ->when('find', 1)
    ->thenReturn(new User());

4. PestPHP Integration

Extend PestTestCase:

uses(Mockista::class)->in('Tests');

it('tests a service', function () {
    $mock = Mockista::mock(Service::class)
        ->when('doWork')
        ->thenReturn('done');

    $this->assertEquals('done', $mock->doWork());
});

5. Dynamic Method Mocking

For methods with variable arguments:

$mock = Mockista::mock(Calculator::class)
    ->when('sum', [1, 2, 3])
    ->thenReturn(6);

Advanced Patterns

1. Mocking Closures

$mock = Mockista::mock(EventDispatcher::class)
    ->when('dispatch')
    ->thenCallback(fn ($event) => $event->handle());

2. Stateful Mocks (Workaround)

Use a closure to track state:

$mock = Mockista::mock(Counter::class)
    ->when('increment')
    ->thenCallback(function () use (&$count) {
        return ++$count;
    });

3. Mocking Static Methods

Stub __callStatic manually:

$mock = Mockista::mock(Helper::class)
    ->partialMock()
    ->whenStatic('generateId')
    ->thenReturn('123');

4. Verifying Interactions

Use PHPUnit assertions:

$mock = Mockista::mock(Service::class)
    ->when('process')
    ->thenReturn(true);

$service->process();
$this->assertTrue($mock->wasCalled('process'));

Gotchas and Tips

Pitfalls

  1. No Native Static Method Support

    • Issue: Mockista doesn’t handle static methods out of the box.
    • Fix: Use partial mocking with __callStatic:
      $mock = Mockista::mock(Helper::class)
          ->partialMock()
          ->__callStatic('generateId', fn() => '123');
      
  2. Partial Mocking Limitations

    • Issue: Partial mocks may not work as expected with Laravel’s magic methods (e.g., __get).
    • Fix: Prefer interface mocking or full class mocks.
  3. Closure Scope Issues

    • Issue: Closures in thenCallback() lose context.
    • Fix: Use use (&$var) to bind variables:
      $count = 0;
      $mock->when('increment')->thenCallback(function () use (&$count) {
          return ++$count;
      });
      
  4. IDE Autocompletion Gaps

    • Issue: No PHPStorm/VSCode support for Mockista’s fluent methods.
    • Fix: Use @var casts or IDE-specific mock generation plugins.
  5. Laravel Service Container Conflicts

    • Issue: Mockista mocks may not resolve correctly in the container.
    • Fix: Bind mocks explicitly:
      $this->app->bind(UserRepository::class, fn() => $mock);
      
  6. Exception Handling Quirks

    • Issue: thenThrow() may not propagate exceptions as expected.
    • Fix: Use PHPUnit’s expectException():
      $this->expectException(RuntimeException::class);
      $mock->query();
      

Debugging Tips

  1. Verify Mock Behavior Use PHPUnit’s assertions:

    $this->assertTrue($mock->wasCalled('method'));
    $this->assertEquals($expected, $mock->getLastCallArgs());
    
  2. Inspect Mock Internals Dump the mock’s call history:

    var_dump($mock->getCallHistory());
    
  3. Fallback to PHPUnit For complex cases, mix Mockista with PHPUnit:

    $mock = Mockista::mock(Service::class)
        ->method('complexMethod')
        ->willReturn($this->getMockBuilder(ComplexClass::class)->getMock());
    
  4. Handle Dynamic Method Names Use regex or closures for dynamic methods:

    $mock->when('method_.*')->thenReturn('default');
    

Configuration Quirks

  1. Autoloading Ensure Mockista is autoloaded in composer.json:

    "autoload-dev": {
        "psr-4": {
            "Mockista\\": "vendor/janmarek/mockista/src"
        }
    }
    
  2. PHPUnit Bootstrapping Add Mockista’s autoloader to phpunit.xml:

    <php>
        <autoload>
            <classmap prefix="Mockista"/>
        </autoload>
    </php>
    
  3. Laravel Testing Helpers Override Laravel’s createMock() in phpunit.xml:

    <php>
        <server name="APP_ENV" value="testing"/>
        <constants>
            <constant name="MOCKISTA_ENABLED" value="true"/>
        </constants>
    </php>
    

Extension Points

  1. Custom Mock Builders Extend Mockista\Builder for domain-specific mocks:

    class UserMockBuilder extends Mockista\Builder {
        public function withDefaultUser() {
            return $this->when('find', 1)->thenReturn(new User());
        }
    }
    
  2. **Lar

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity