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

inventsimple's avatar

PHPUNIT Testing orderby? Can it be done?

Is there a way to test for ordered by return of data? I know this is a pretty simple question, but I've not been able to find much on it.

0 likes
10 replies
ifpingram's avatar

@inventsimple I'm sorry but I don't understand the question. Are you referring to the results of database queries, Eloquent collections or some other data object? Perhaps you can elaborate with an example of the data you are playing with, and we can try to see what can be done...

inventsimple's avatar

No problem, something like the code below. I know it's best to use mockery but I'm still fairly new to phpunit testing so feel free to criticize away :)

  public function retrieve_all_rows_from_watchdog_table_and_sort_by_datecreated_desc()
  {
    // get all rows from database table order by DESC
    $results = Watchdog::orderBy('dateCreated', 'DESC')->get();
    $countRows = $results->count();
    
    // Test for order by

    // Test for more rows than 0
    $this->assertGreaterThan(0, $countRows);
  }

So I want to make sure that I'm always getting data that's ordered by the dateCreated column in descending order.

and thank you for the advice @ifpingram in advance

spekkionu's avatar

You can loop through the results and assert that each date is >= to the previous.
You can also seed the database with specific records and verify that they are returned in the order you expect.

Really though it looks like you are just testing Eloquent and the query builder which already have their own tests.
Your testing time would be much better spent elsewhere.

2 likes
xingredient's avatar

Hi,

I know this is an old post but I still wanted to reflect on your answer as I think it might be usefull for people finding this.

I do not fully agree on that he's trying to test Eloquent. He could need an output that is ordered, if he refactors the code and forgets to add the orderBy it could break his functionality, hence the testing of the order is a valid one.

ifpingram's avatar

@inventsimple as @spekkionu says, the thing to do is to seed the database then test against it, but as he also says, you are only testing Eloquent and thus this test is redundant.

Testing should be for the code / objects which you are writing. What is it that you actually wish to do with these rows when you retrieve them? That's the code which you want to be testing...

1 like
channaveer's avatar

As your trying to test the behaviour of the framework whether it sorts in ascending or descending order.

I have read and seen many of them commenting that we need to focus on Testing Our Code rather than testing the framework.

But the following should be a good start for testing that usecase

Watchdog::factory()->create(["dateCreated" => "2021-09-01 00:00:00"]);
Watchdog::factory()->create(["dateCreated" => "2021-09-02 00:00:00"]);
$results = Watchdog::orderBy('dateCreated', 'DESC')->get();

$this->assertCount(2, $results->toArray());

$this->assertEquals("2021-09-02 00:00:00", $results[0]->dateCreated);
$this->assertEquals("2021-09-01 00:00:00", $results[1]->dateCreated);
1 like
kevinbui's avatar

I learnt this trick from the test-driven laravel course. You might want to try something like this:

public function testGetLatestCustomerOrders()
{
    $customer = Customer::factory()->hasOrders(4)->create();

    $response = $this->get("/api/customers/{$customer->id}/orders");

    $this->assertEquals(
        $customer->orders()->latest()->pluck('id')->toArray(),
        collect($response['orders'])->pluck('id')->toArray()
    );
}
1 like
alazark's avatar

You can also use the getData() method on the response

public function test_get_latest_customer_orders()
{
    $customer = Customer::factory()->hasOrders(4)->create();
    $response = $this->get("/api/customers/$customer->id/orders");
    $data = $response->getData()->data;

    $this->assertTrue($data[0]->id > $data[1]->id);
}

In this case you can actually test from the response. This example assumes you have a data wrapper on your response

Please or to participate in this conversation.