composer require mpyw/laravel-database-mock mpyw/mockery-pdo:dev-alpha
phpunit.xml):
<php>
<env name="MOCKERY" value="1"/>
</php>
use Mpyw\LaravelDatabaseMock\Facades\DBMock;
public function test_user_creation()
{
$pdo = DBMock::mockPdo();
$pdo->shouldInsert(
'insert into `users` (...) values (?, ?, ?)',
['John', 'john@example.com', '2023-01-01 00:00:00']
)->shouldReturn(1);
$user = User::create([...]);
$this->assertEquals(1, $user->id);
}
Replace a flaky database-dependent test with a mocked query:
public function test_user_query()
{
$pdo = DBMock::mockPdo();
$pdo->shouldSelect('select * from users where id = ?')
->shouldFetchAllReturns([['id' => 1, 'name' => 'John']]);
$user = User::find(1);
$this->assertEquals('John', $user->name);
}
public function setUp(): void
{
parent::setUp();
$this->pdo = DBMock::mockPdo(); // Global mock for all tests
}
$this->pdo->shouldSelect('SELECT * FROM orders WHERE user_id = ?')
->shouldFetchAllReturns([['id' => 1, 'amount' => 100]]);
$orders = Order::where('user_id', 1)->get();
$this->assertCount(1, $orders);
$this->pdo->shouldHaveReceived('insert');
public function test_user_with_posts()
{
$pdo = DBMock::mockPdo();
$pdo->shouldSelect('SELECT * FROM users WHERE id = ?')
->shouldFetchAllReturns([['id' => 1, 'name' => 'John']]);
$pdo->shouldSelect('SELECT * FROM posts WHERE user_id = ?')
->shouldFetchAllReturns([['id' => 1, 'title' => 'Hello']]);
$user = User::with('posts')->find(1);
$this->assertEquals('Hello', $user->posts[0]->title);
}
public function test_read_write_separation()
{
$pdos = DBMock::mockEachPdo();
$pdos->reader()->shouldSelect('SELECT * FROM products')
->shouldFetchAllReturns([['id' => 1, 'name' => 'Laptop']]);
$pdos->writer()->shouldInsert('INSERT INTO orders (...)')
->shouldReturn(1);
$product = Product::first();
Order::create([...]);
}
public function test_transaction_rollback()
{
$pdo = DBMock::mockPdo();
$pdo->shouldBeginTransaction();
$pdo->shouldInsert('INSERT INTO logs (...)')
->shouldThrow(new \Exception('DB Error'));
$this->expectException(\Exception::class);
DB::transaction(function () {
Log::create([...]);
});
}
public function test_dynamic_where_clause()
{
$pdo = DBMock::mockPdo();
$pdo->shouldReceive('prepare')
->with('SELECT * FROM users WHERE name = ?')
->andReturnSelf();
$pdo->shouldReceive('execute')
->with(['John'])
->andReturnSelf();
$pdo->shouldReceive('fetchAll')
->andReturn([['id' => 1, 'name' => 'John']]);
$user = User::where('name', 'John')->first();
$this->assertEquals(1, $user->id);
}
public function test_database_error_handling()
{
$pdo = DBMock::mockPdo();
$pdo->shouldSelect('SELECT * FROM invalid_table')
->shouldThrow(new \PDOException('SQLSTATE[42S02]: Base table'));
$this->expectException(\PDOException::class);
User::where('id', 1)->first();
}
public function test_timestamp_mocking()
{
Carbon::setTestNow('2023-01-01 12:00:00');
$pdo = DBMock::mockPdo();
$pdo->shouldInsert('INSERT INTO events (...)')
->shouldReturn(1);
$event = Event::create([...]);
$this->assertEquals('2023-01-01 12:00:00', $event->created_at->format('Y-m-d H:i:s'));
}
Query Mismatch Errors
DB::enableQueryLog() to inspect real queries:
DB::enableQueryLog();
User::all();
dd(DB::getQueryLog()); // Copy the exact query for mocking
Parameter Binding Order
shouldInsert() expects parameters in the same order as the query.$pdo->shouldInsert('INSERT INTO users (name, email) VALUES (?, ?)', ['John', 'john@example.com']);
Global vs. Per-Test Mocks
DBMock::mockPdo()) persist across tests, causing flakiness.public function tearDown(): void
{
DBMock::reset();
parent::tearDown();
}
Carbon Timestamp Conflicts
Carbon::setTestNow() may conflict with other time-mocking tools (e.g., PestPHP).public function tearDown(): void
{
Carbon::setTestNow(null);
parent::tearDown();
}
Read/Write Replica Misconfiguration
DBMock::mockEachPdo() for replica setups.Alpha Dependency Risks
mockery-pdo is in alpha; may introduce breaking changes.composer require mpyw/mockery-pdo:dev-alpha#1.0.0-alpha1
Inspect Mocked Queries
getMock() to debug:
$mock = DBMock::mockPdo()->getMock();
var_dump($mock->getInvocations());
Verify Expectations
$this->assertTrue($pdo->shouldHaveReceived('select'));
Log Unmocked Queries
DB::listen(function ($query) {
if (!str_contains($query->sql, 'mocked_query')) {
$this->fail("Unexpected query: " . $query->sql);
}
});
Handle Dynamic SQL
DB::raw()), mock the PDO layer directly:
$pdo = DBMock::mockPdo();
$pdo->shouldReceive('prepare')
->with('SELECT * FROM users WHERE id = :id')
->andReturnSelf();
$pdo->shouldReceive('execute')
->with(['id' => 1])
->andReturnSelf();
$pdo->shouldReceive('fetchAll')
->andReturn([['id' => 1, 'name' => 'John']]);
DBMock::mockPdo
How can I help you explore Laravel packages today?