Installation:
composer require imanghafoori/eloquent-mockery --dev
Add to composer.json under require-dev to avoid production bloat.
First Use Case:
Mock a simple User model query in a test:
use Imanghafoori\EloquentMockery\EloquentMockery;
public function test_find_user()
{
EloquentMockery::mock(User::class, [
'find(1)' => User::factory()->make(['name' => 'Test User'])
]);
$user = User::find(1);
$this->assertEquals('Test User', $user->name);
}
Key Files:
tests/TestCase.php: Ensure EloquentMockery is available via use.config/testing.php: Check for any test-specific configurations (though this package is config-free).Mocking Queries:
// Mock a single method call
EloquentMockery::mock(User::class, [
'find(1)' => User::factory()->make(),
'where("active", 1)->get()' => User::factory()->count(3)->make()
]);
// Mock with dynamic parameters
EloquentMockery::mock(User::class, [
'findOrFail(?)' => fn($id) => User::factory()->make(['id' => $id])
]);
Conditional Mocking: Use closures for dynamic responses:
EloquentMockery::mock(User::class, [
'whereHas("posts", fn($q) => $q->where("published", 1))' => fn() => User::factory()->count(2)->make()
]);
Resetting Mocks: Clear mocks between tests:
EloquentMockery::reset(User::class);
Integration with Factories: Combine with Laravel’s factories for realistic test data:
EloquentMockery::mock(User::class, [
'find(1)' => User::factory()->state(['verified_at' => now()])->create()
]);
Mocking Relationships:
EloquentMockery::mock(User::class, [
'posts' => Post::factory()->count(2)->make()
]);
beforeEach: Reset mocks in setUp() or beforeEach():
public function setUp(): void
{
EloquentMockery::reset(User::class);
parent::setUp();
}
Global State:
EloquentMockery::reset() or wrap mocks in beforeEach.Method Signature Mismatches:
findOrFail(?) vs. findOrFail($id)).fn($id) => ... for dynamic parameters.Lazy Loading:
posts) are eager-loaded by default. For lazy loading, use:
EloquentMockery::mock(User::class, [
'posts' => fn() => Post::factory()->count(1)->make()
]);
Database Transactions:
Static Method Mocking:
User::boot()), use PHP’s Mockery directly.$this->assertTrue(EloquentMockery::isMocked(User::class));
$this->assertEquals(1, EloquentMockery::mockCount(User::class));
dd() to inspect mocked responses:
EloquentMockery::mock(User::class, [
'find(1)' => fn() => dd('Mocked call triggered') ?: User::factory()->make()
]);
Custom Mock Providers: Extend the package by creating a trait or helper for reusable mock setups:
trait UserMocks
{
protected function mockActiveUser()
{
EloquentMockery::mock(User::class, [
'find(1)' => User::factory()->active()->make()
]);
}
}
Integration with Pest:
Use Pest’s beforeEach for cleaner mock management:
beforeEach(function () {
EloquentMockery::reset(User::class);
});
Performance:
For large-scale mocking, consider caching factory responses or using Mockery directly for complex scenarios.
Edge Cases:
save() or delete() methods to simulate persistence:
EloquentMockery::mock(User::class, [
'save()' => true, // Simulate successful save
'delete()' => null // Simulate soft delete
]);
How can I help you explore Laravel packages today?