Support the ongoing development of Laravel.io →
Eloquent Testing
Last updated 2 years ago.
0

Mocking eloquent models is difficult and leaves your tests very brittle.

If you ever refactor the getOrders() method the tests will break, as your testing specific API calls within this method, not simply testing the return values or functionality of the method.

You would be better suited to do integration tests. Integrations tests are run within an 'integrated system', that means with a database and real world data.

The reason that you really should do this is a naunce of the active record pattern that Eloquent uses. In active record ORMs your models or entities are coupled to the ORM itself, to be honest your models ARE your ORM. Therefore its not really possible to seperate the two when testing. That is why it is recommended to do integration tests when testing Laravel models.

Another tip? When writing test methods in place of naming you functions:

public function testGetUsersOrders()
{
    // ...

I opt for the following "PHPSpec like" naming convention:

/** @test */
public function it_gets_user_orders()
{
    // ...

Its far more readable, if you return to this test at a later date you, or another developer instantly know what its testing. Not only that but it create a very readable form of documentation for your entire system.

hope all this helps

Last updated 9 years ago.
0

andrewmclagan said:

Mocking eloquent models is difficult and leaves your tests very brittle.

If you ever refactor the getOrders() method the tests will break, as your testing specific API calls within this method, not simply testing the return values or functionality of the method.

You would be better suited to do integration tests. Integrations tests are run within an 'integrated system', that means with a database and real world data.

The reason that you really should do this is a naunce of the active record pattern that Eloquent uses. In active record ORMs your models or entities are coupled to the ORM itself, to be honest your models ARE your ORM. Therefore its not really possible to seperate the two when testing. That is why it is recommended to do integration tests when testing Laravel models.

Another tip? When writing test methods in place of naming you functions:

public function testGetUsersOrders()
{
   // ...

I opt for the following "PHPSpec like" naming convention:

/** @test */
public function it_gets_user_orders()
{
   // ...

Its far more readable, if you return to this test at a later date you, or another developer instantly know what its testing. Not only that but it create a very readable form of documentation for your entire system.

hope all this helps

Thanks for reply Andrew. Integration test was my first try. Problem is that I access Auth::id() within scopeForUser method which is not set in time of running the test (I updated post), even if I log in user within testGetUsersOrders() method. That means if I run the test, Auth::id() returns NULL in scopeForUser(). It's beause of different instances of Auth.

Note that in api test I call $this->call('GET', '/order'); and not directly calling user model's getOrders method. But it's on new topic which I created on stackoverflow before. Do you have any ideas how to get trough this? Thank you

Last updated 9 years ago.
0

I'm really late to the party, but this comment might be useful for other people.

In my opinion, it's a mistake to couple your models directly to the Auth facade. This immediately limits the functionality of the query scope in this example to the logged in user. What happens if later down the road, you want to build an administration panel and see all orders for a single user? Your functionality would work only with the currently authenticated user.

Instead, pass the user ID into your query scope.

public function scopeForUser($query, $userId)
{
    return $query->where('user_id', $userId);
}

With this approach, you can pass the current user ID into the query scope from your controller and likewise, pass in any ID you like during your unit tests.

Last updated 9 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

fogine fogine Joined 8 Jan 2015

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.