Is it possible to mock or fake the output of a model method in Laravel 5.8?
For example, consider this model
class Website extends Model
{
public function checkDomainConfiguration($domain): bool
{
try {
$records = dns_get_record($domain, DNS_A);
} catch (ErrorException $e) {
return false;
}
if (isset($records[0]['ip']) && $records[0]['ip'] === $this->server->ipv4_address) {
return true;
}
return false;
}
}
for the purpose of the test, I need to tell phpunit that when this method fires (it is called in the controller), to return true, or false if I purposely want it to fail. In the test I factory up a website, and of course it will fail the php method dns_get_record.
I've read the Laravel docs, and scoured google about mocking model methods, but can't seem to find anything, short of wrapping a big if around the method that checks if i'm not in testing mode, and if i am just return true. <-- YUK.
UPDATE This is an example of how I call the method in the controller
class SomeController extends Controller
{
public function store(Website $website, Domain $domain)
{
if (! $website->checkDomainConfiguration($domain->domain)) {
return response([
'error' => 'error message'
], 500);
}
// continue on here if all good.
}
}
This is some code from the test
$website = factory(Website::class)->create();
$domain = factory(Domain::class)->create([
'website_id' => $website->id
]);
//Mock the website object
$websiteMock = \Mockery::mock(Website::class)->makePartial();
$websiteMock->shouldReceive('getAttribute')
->once()
->with('domain')
->andReturn($website->domain);
$websiteMock->shouldReceive('checkDomainConfiguration')
->with($domain->domain)
->andReturn(true);
app()->instance(Website::class, $websiteMock);
// tried end point like this
$response = $this->json(
'POST',
'api/my-end-point/websites/' . $website->domain . '/domain/' . $domain->id
);
//also tried like this
$response = $this->json(
'POST',
'api/my-end-point/websites/' . $websiteMock->domain . '/domain/' . $domain->id
);
The controller method accepts the website and the domain model bindings. if I dd(get_class($website)) at the top of the controller, it display the namespace for the actual model, not the mock.