I have in my code a line like this:
ModelName::create($data);
where ModelName is just an Eloquent
model. Is there a way to mock this call inside a unit test? I tried with:
$client_mock = \Mockery::mock('Eloquent','App\Models\ModelName');
$client_mock->shouldReceive('create')
->with($data)->andReturns($returnValue);
but it doesn't work.
If you need to mock a static method, it is a strong indicator for a bad design. Usually, you mock the dependency of your class-under-test. If your class-under-test refers to a static method - like java.
Because there is no instance variable, the class name itself should be used to access the members of a static class. The powerful capabilities of the feature-rich JustMock framework allow you to mock static classes and calls to static members like methods and properties, set expectations and verify results.
Therefore, any logic which can be shared among multiple instances of a class should be extracted and put inside the static method. PHP static methods are most typically used in classes containing static methods only often called utility classes of PHP frameworks like Laravel and CakePHP.
When testing Laravel applications, you may wish to "mock" certain aspects of your application so they are not actually executed during a given test. For example, when testing a controller that dispatches an event, you may wish to mock the event listeners so they are not actually executed during the test.
You should do something like this:
$client_mock = \Mockery::mock('overload:App\Models\ModelName');
$client_mock->shouldReceive('create')->with($data)->andReturn($returnValue);
We are using overload:
because you don't want to pass mock to some class, but you want to use it also in case it's hard-coded into some classes.
In addition to your test class (just before class
) you should add:
/**
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
to avoid errors that this class was already loaded (it might work without it in single test but when you are running multiple tests probably it won't).
You might read Mocking hard dependencies for details about it.
UPDATE
In some cases it might be not possible to mock classes using this method. In those cases you can create a normal mock (without overload
) and inject it to the service container like so:
App::instance('\App\Models\ModelName', $client_mock);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With