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

edgreenberg's avatar

what to test when doing an eloquent select query?

If I query

$result = ModelName::where(whatever)->get() 

I expect a collection of results.

Of course, there are a whole bunch of things that can go wrong.

  • no records returned
  • no table associated with model
  • heck, I can't think of all of them

So what should I test for:

  • a thrown error?
  • null?
  • an empty collection?

And what means what?

This isn't all documented in one place. One would have to follow through all the code. Honestly I got lost in the code for get() at https://github.com/laravel/framework/blob/6.x/src/Illuminate/Database/Eloquent/Builder.php#L523

Does anybody have a practical guide to all the various things to test?

Thanks, Ed

0 likes
5 replies
LaryAI's avatar
Level 58

When testing an Eloquent select query, you should test for the following:

  1. Test that the query returns a collection of results.
  2. Test that the query returns an empty collection if no records are found.
  3. Test that the model is associated with a table.

To test for these conditions, you can use PHPUnit and Laravel's testing helpers. Here's an example:

public function testSelectQuery()
{
    // Test that the query returns a collection of results.
    $result = ModelName::where('whatever', 'value')->get();
    $this->assertInstanceOf(\Illuminate\Database\Eloquent\Collection::class, $result);

    // Test that the query returns an empty collection if no records are found.
    $result = ModelName::where('whatever', 'non-existent-value')->get();
    $this->assertEmpty($result);

    // Test that the model is associated with a table.
    $this->assertEquals('table_name', (new ModelName)->getTable());
}

In the first test, we use assertInstanceOf to check that the result is an instance of Illuminate\Database\Eloquent\Collection.

In the second test, we use assertEmpty to check that the result is an empty collection.

In the third test, we use assertEquals to check that the model is associated with the correct table.

tykus's avatar

An empty Collection still is a Collection of results? Depending on the constraints; you should expect 0 or more results, right?

It is difficult to give any direction for such an abstract case; and I don't know why you would need to test an Eloquent query in isolation from your application like this; maybe provide more context!

edgreenberg's avatar

@tykus Thanks for the reply. The use case is an API. I am happy to return an empty array, derived from an empty collection, a populated array, or to return 400 or 500 if the Eloquent call throws an error.

What I'm unsure of is whether the Eloquent get can return null or false, and what that might mean. I need to return a 400 series or 500 series error. If the call cannot return null or false, no need to check for them.

I'm hoping to send a reasonable explanation of the problem as a json response with the failure so that the trouble report from the consumer will be more useful.

It just didn't seem right to not know what I might get back.

Anyway, if the call throws an error, I'm OK, and I'm not going to worry much about null or false, since they don't seem to be valid returns from the get() at the end of the call.

tykus's avatar

@edgreenberg an Eloquent get query will always return a Collection - assuming the query is valid (does not produce invalid SQL). What might you be doing with the query so that it might produce invalid SQL?

jlrdw's avatar

Curious, why test an sql query, that is already tested with Mysql team, php team, and laravel team to ensure they work.

And even if you write a test wrong, the real query will probably work. Custom code is where I'd test, especially areas to refactor.

I have seen dozens of post where you see: "My test fails", but the real code works. So I would also be concerned about things working for real, not a bunch of test (except for test looking for areas to refactor).

The opposite happens, test pass, but real code is messed up. Just my opinion, but look at for real over a bunch of test that really don't tell you much.

Edit:

A GROUP BY is a great example where you can get results, but wrong results depending on how it's written.

The only true way to verify a GROUP BY is with some known correct results to compare.

Please or to participate in this conversation.