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.
composer require janmarek/mockista --dev
getMockBuilder() with Mockista’s fluent interface:
use Mockista\Mockista;
$mock = Mockista::mock(UserRepository::class)
->method('find')
->returns($user);
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);
}
getMockBuilder() patterns with Mockista’s equivalents.// Replace:
$mock = $this->getMockBuilder(Service::class)
->disableOriginalConstructor()
->onlyMethods(['fetch'])
->getMock();
// With:
$mock = Mockista::mock(Service::class)
->method('fetch')
->returns($data);
$mock = Mockista::mock(OrderService::class)
->when('calculateTotal', [10, 2]) // Method + args
->thenReturn(20.00)
->when('applyDiscount', [20.00, '10%'])
->thenReturn(18.00);
$mock = Mockista::mock(Database::class)
->when('query')
->thenThrow(new RuntimeException('DB down'));
// Mock only specific methods in a class
$mock = Mockista::mock(User::class)
->partialMock()
->when('save')
->thenReturn(true);
$mock = Mockista::mock(Logger::class)
->when('log')
->thenCallback(function ($level, $message) {
return "[$level] $message";
});
Use Mockista with Laravel’s MockFacade:
$mock = Mockista::mock(Auth::class)
->method('check')
->returns(true);
For container-bound services, bind the mock directly:
$this->app->instance(
UserRepository::class,
Mockista::mock(UserRepository::class)
->when('find', 1)
->thenReturn(new User())
);
Create a mock interface and adapter:
interface UserRepositoryInterface {
public function find(int $id);
}
$mock = Mockista::mock(UserRepositoryInterface::class)
->when('find', 1)
->thenReturn(new User());
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());
});
For methods with variable arguments:
$mock = Mockista::mock(Calculator::class)
->when('sum', [1, 2, 3])
->thenReturn(6);
$mock = Mockista::mock(EventDispatcher::class)
->when('dispatch')
->thenCallback(fn ($event) => $event->handle());
Use a closure to track state:
$mock = Mockista::mock(Counter::class)
->when('increment')
->thenCallback(function () use (&$count) {
return ++$count;
});
Stub __callStatic manually:
$mock = Mockista::mock(Helper::class)
->partialMock()
->whenStatic('generateId')
->thenReturn('123');
Use PHPUnit assertions:
$mock = Mockista::mock(Service::class)
->when('process')
->thenReturn(true);
$service->process();
$this->assertTrue($mock->wasCalled('process'));
No Native Static Method Support
__callStatic:
$mock = Mockista::mock(Helper::class)
->partialMock()
->__callStatic('generateId', fn() => '123');
Partial Mocking Limitations
__get).Closure Scope Issues
thenCallback() lose context.use (&$var) to bind variables:
$count = 0;
$mock->when('increment')->thenCallback(function () use (&$count) {
return ++$count;
});
IDE Autocompletion Gaps
@var casts or IDE-specific mock generation plugins.Laravel Service Container Conflicts
$this->app->bind(UserRepository::class, fn() => $mock);
Exception Handling Quirks
thenThrow() may not propagate exceptions as expected.expectException():
$this->expectException(RuntimeException::class);
$mock->query();
Verify Mock Behavior Use PHPUnit’s assertions:
$this->assertTrue($mock->wasCalled('method'));
$this->assertEquals($expected, $mock->getLastCallArgs());
Inspect Mock Internals Dump the mock’s call history:
var_dump($mock->getCallHistory());
Fallback to PHPUnit For complex cases, mix Mockista with PHPUnit:
$mock = Mockista::mock(Service::class)
->method('complexMethod')
->willReturn($this->getMockBuilder(ComplexClass::class)->getMock());
Handle Dynamic Method Names Use regex or closures for dynamic methods:
$mock->when('method_.*')->thenReturn('default');
Autoloading
Ensure Mockista is autoloaded in composer.json:
"autoload-dev": {
"psr-4": {
"Mockista\\": "vendor/janmarek/mockista/src"
}
}
PHPUnit Bootstrapping
Add Mockista’s autoloader to phpunit.xml:
<php>
<autoload>
<classmap prefix="Mockista"/>
</autoload>
</php>
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>
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());
}
}
**Lar
How can I help you explore Laravel packages today?