Mock Laravel Model in phpunit test - laravel

I am persuing unit test and here i don't want to use the database. And i am doing mocking of each and everything. But i am unable to mock Models. If i try to mock the model with override then it gives me this error: class already exists. And if i tried without overide then the mocking is not working. I also found a trait For it named laravel query factory, which helps me to give a dummy query builder. But i am facing one issue in it. When i use count funtion on model then it gives me following error:
ErrorException: Undefined index: aggregate
Meanwhile i am not able to mock in any way, anyone please help me to do the same
Here is the model Query which i want to mock:
MyModel::where('column_name', 12)->count();

Related

Mockery Laravel Elequent chained queries

I have a question regarding mockery in combination with Laravel.
I have sucessfully created a mockery object to mock all the public static methods such as where and find on the elequent model instance.
$userMock = \Mockery::mock('alias:App\Models\User');
This works great, however testing chained queries like I ran into some issues:
User::where("name", "test")->first()
The only solution I could find is to use mock the demeter chain using: http://docs.mockery.io/en/latest/reference/demeter_chains.html
So for example:
$userMock->shouldReceive('where->first')->andReturn($user);
But I would like to test the arguments that are provided to the where query as well:
$userMock->shouldReceive("where")->with("slug", "test")->andReturn($user);
But that is not really working since it should return the Elequent builder, any ideas how I can test this properly?
$userMock->shouldReceive('where')
->with("slug", "test")
->andReturn(Mockery::self())
->shouldReceive("first")
->andReturn($user);
Using Mockery::self you can complete the chain.

Laravel mock interface

tell me how you can make fun of the interface. Otherwise, you replace the interface with the implemented class, then the test passes. The most interesting thing is that the code works with the interface.
Gist
With the interface, I get the error:
Mockery\Exception\InvalidCountException : Method send(<Any Arguments>) from Mockery_0_App_Services_SmsNotification_SmsInterface should be called
exactly 1 times but called 0 times
How do I implement the test?
On line 36 of ExampleTest.php,
$user->notify(new CreateUploadUpdateTask(new SmsMessage()));
The notify() method comes from Illuminate\Notifications\Notifiable trait, right? If so, you can fake the notification as described in this link.
Besides, if you send notifications using the Notification facade, then you can mock the facade as described in this link.
Please try to name your test classes and methods as descriptive as possible so that one can quickly realize what are you trying to test just from reading the test class or method name.

Return to controller on FormRequest validation failure

I'm trying to make an API with laravel and I'm trying to validate a few query parameters using FormRequest. My problem is that when the validator fails I still want to carry on using the controller as it does when it passes but I can't for the life of me figure out how to do this. I know I have to override the failedValidation() function but I'm not sure what to override it with to get my desired result.
Any help would be appreciated.

STI ::find() fails in controller but succeeds in tinker

I'm using MannikJ/laravel-sti but the following code has a different behaviour in tinker and in a controller (assuming the definitions in larevel-sti's documentation, with classes Root, Sub1 and Sub2):
Root::find(1234)
In tinker, it correctly returns an instance of Sub1. But in a controller, it returns null.
I get the correct instance in the controller if I replace the code with:
Sub1::find(1234)
Thanks to the maintainer (cf. issue #1), we found that the problem is that we use constructors in our objects but laravel-sti's trait also does. Constructors are a known issue in PHP with traits…

Learning WardrobeCMS source code, how do they retrieve posts without db request?

Newbie here. I'm learning Laravel and WardrobeCMS is a good one to study IMO. Just wondering if you guys could point me how they retrieve posts with requesting db?
In homepage, the HomeController has this line.
$posts = $this->posts->active(Config::get('core::wardrobe.per_page'));
In WardrobeServiceProvider, they bind PostRepoitory with DbPostRepository and here is their 'active' method.
public function active($per_page)
{
$per_page = is_numeric($per_page) ? $per_page : 5;
\Debugbar::info('calling posts active method');
return Post::with(array('tags', 'user'))
->where('active', 1)
->where('publish_date', '<=', new DateTime)
->orderBy('publish_date', 'desc')
->paginate($per_page);
}
The return statement looks like the Eloquent command but I don't see any db request in Debugbar console. How does this work? Please advise.
I am a designer trying to learn coding and Laravel 'illuminates' me. In my current dev project, I have around 4-10 db calls in each page. My goal here is to reduce db calls as much as possible and I think WardrobeCMS source code is my starting point.
Post::with()->where()->paginate(); doesn't always 'call' database?
In short: Yes it does!
Post is an Eloquent ORM because, basically every model (i.e. Post) in Laravel extends the Eloquent/Model class and this Eloquent/Model class uses Query Builder (DB in your case) class along with other classes to query the database and in your example, the Post is something like this:
class Post extends Eloquent {
// ...
}
SInce the Post class extends the Eloquent class so Post have access (inherited from Eloquent) to all (protected and public only) methods of Eloquent class, so, if the Eloquent has a function/method like this (actually has):
public function with($relation)
{
//...
}
Then the Post class can call that function/method like this:
Post::with()
So, actually Post::with()->where()->paginate() call interact with database in this case but it's not necessary that every database interaction has to be using DB::table(), instead, it's a convenient way to query the database using an ORM and don't forget that, the ORM is just a wrapper over the query builder, behind the scene, the Post Eloquent Model is using the query builder.
You should the manual instead of reading the source code of another application, once you get the basic idea then you may read source code of other Laravel applications to get some ideas that other developers uses.
Update: If you are not seeing any queries in the debugger then the application is using the caching feature of Laravel to cache database queries for a certain period of time so it can use those later without interacting with the database to speed up the process.

Resources