Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Steph's avatar
Level 1

How to make Laravel partially mock the DB facade ?

Hi everyone ! Little lost with the mocking system in Laraval 10.x. PHPUnit permits to mock a class partially (->makePartial()). E.g., with this test case :

	public function testUpdateVehicleList_withDBException()
	{
		DB::shouldReceive('update')->once()->andThrow(new \Exception());
		$toolsController = new ToolsController;
		$response = $toolsController->UpdateVehicleList(true);
	}

UpdateVehicleList is a controller method calling different DB functions (update() - the one I want to throw an exception, table(), orderBy(), etc.). When that test runs, Laravel complains at each of those calls ABOVE the first "update" call in the code (e.g. Method Mockery_2_Illuminate_Database_DatabaseManager::table() does not exist on this mock object), which makes me believe that, by default, Laravel doesn't mock partially.

The problem is that I don't seem to find the correct way to make it partially mock the DB facade (or I don't know how to ask Google, which is probably the reason). Does it ring a bell to anyone ?

EDIT:

I made progress with this addition:

	public function testUpdateVehicleList_withDBException()
	{
		DB::shouldReceive('update')->once()->andThrow(new \Exception());
-->	    DB::makePartial();
		$toolsController = new ToolsController;
		$response = $toolsController->UpdateVehicleList(true);
	}

But the DB still seems to be completely mocked up, as I got an error Trying to access array offset on value of type null, which indicated that the DB facade is still working strangly...

EDIT 2:

Debugger the test in VSCode with this second version (BD::makePartial), within the phpunit framework (eval 1.php), at the call of DB::table(...) I find a $this->_mockery_partial set to null in _mockery_handleMethodCall(), thus the mockup version of DB::table() is called. Once again, does it ring a bell to anyone ?

0 likes
2 replies
mike_isp's avatar
mike_isp
Best Answer
Level 3

Rather than mock the DB facade, I'd let your test modify (or not modify as the case may be) data, and assert against that.

e.g. configure phpunit.xml to use a test DB, have your test send a request to the controller action, and assert that the DB records are how you would expect them to be. This is a more realistic test than mocking parts of the framework.

I'd also suggest simulating the request rather than calling controller methods directly.

public function testUpdateVehicleList_withDBException()
{
	// create models etc
	$response = $this->post(route('tools.updateVehicles'));
}
Steph's avatar
Level 1

Grrr, you are right ! I've spent so much time on this problem that I lost sight on the fact that what is best to test an exception handling is simply to make the code naturally throw the said exception, and not fake it ! Thank you very much for your advice :)

1 like

Please or to participate in this conversation.