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

Lopsum's avatar
Level 5

Trouble recovering the Model in my tests

Hello, I'm just starting out with implementing unit tests in Laravel using Pest. I have an application running with FilamentPHP, and I have conducted a few tests that operate with a GitHub action.

It happens that some tests fail, but not consistently. I have a problem retrieving the object that has just been created by the factory... For exemple :

php No query results for model [App\Models\Order] 1 //Not always ID 1

From time to time a test fails with this error, the next time, when I run the tests again, the test that had an error works but the next one fails. In short, I'm having trouble understanding why...

A configuration issue? A problem with the test DB? My factories? I tried in two ways, either directly with the factory or by retrieving the Model (see examples below).

it('can validate an order from IN_ORDER status', function () {
    $order = Order::factory()->create(['status' => Status::IN_ORDER]);
    // If I dd() the $order, I have a result

    livewire(ViewOrder::class, ['record' => $order->getRouteKey()])
        ->call('validateOrder')
        ->assertHasNoActionErrors();

    $order->refresh();
    expect($order->status)->toBe(Status::VALIDATED);

    $activity = Activity::where('subject_id', $order->id)
        ->where('event', 'validate')
        ->latest()
        ->first();

    expect($activity)->not->toBeNull();
});

And another one :

it('builds the correct title with the reference', function () {
    Order::factory()->create(['reference' => '123456']);

    $order = Order::latest()->first();

    $component = livewire(
        ViewOrder::class,
        ['record' => $order->getRouteKey()]
    ); // Here it tells me that getRouteKey() is null.

    $translationKey = $component->instance()->getTitle();

    $expectedTitle = __($translationKey) . ' #' . $order->reference;

    expect($expectedTitle)->toContain('#123456');
});

Here my TestCase.php :

<?php

namespace Tests;

use Database\Seeders\production\ShieldSeeder;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        $this->seed(ShieldSeeder::class);
    }
}

And my phpunit.xml :

Do you have any idea where the problem might be coming from? Thank you 😅

0 likes
8 replies
newbie360's avatar

@vable I only write Feature Test, no Unit Test, because it require more time, the ShieldSeeder look like a package to handle role and permission?

if the app has multiple locale, how you get that?

it('builds the correct title with the reference', function (string $locale) {
    App::setLocale($locale);

    $order = Order::factory()->create(['reference' => '123456']);

    $component = livewire(
        ViewOrder::class,
        ['record' => $order->getRouteKey()]
    );

    $pageTitle = $component->instance()->getTitle();

    $translatedTitle = __($order->title) . ' #' . $order->reference;

    expect($pageTitle)->toBe($translatedTitle);
})->with(
    Locale::toArray() // imagine you have Enum to contain multiple locale
);
Lopsum's avatar
Level 5

Yes, sorry, these are indeed Feature Tests. The application has only one locale (FR) and will not have any others in the future. It is a Filament application, and indeed, ShieldSeeder comes from a package and allows for populating the table with the associated roles and permissions. 🫣

It may be more specific to Filament; I'm not entirely sure, as ALL my tests work except for the one concerning ViewOrder.php, which extends the ViewRecord class from Filament...

It also fails on GitHub.

https://i.postimg.cc/CLw0cwVj/Capture-d-cran-2025-03-06-105611.jpg

newbie360's avatar

@Vable In the second code block, no need query again?

+   $order = Order::factory()->create(['reference' => '123456']);

-   $order = Order::latest()->first();

In the first code block, why the ViewOrder::class has validation? normally it only contain ALL disabled fields

Lopsum's avatar
Level 5

Thank you for your time :)

I provided two examples of the two methods I tested to retrieve the Model. The first time using just the factory, the second time with a query as well. In both cases, it doesn't work 😅

For the validation, it's because on this page I have actions that open modals with forms allowing for certain processes (validating the order, adding the reference, etc.).

newbie360's avatar

@Vable I'm confusing, is this pass?

test('can render view page', function () {
    $url = OrderResource::getUrl('view', [
        'record' => Order::factory()->create(),
    ]);

    $this->get($url)->assertOk();
});

if the above passed

test('can retrieve data fill the form', function () {
    $order = Order::factory()->create();
    
    $component = livewire(ViewOrder::class, [
        'record' => $order->getRouteKey()
    ]);

    dd($component->getData()); // try debug

    $component
        ->assertFormSet([
            'field_a' => $order->field_a,
            'field_b' => $order->field_b,
            'field_c' => $order->field_c,
        ]);
});
Lopsum's avatar
Level 5

@newbie360 Just like me 😂

To make it a bit clearer for you regarding the layout of the page, take a look at the screenshot below (well, it's in French, but you'll have the basics...)

https://i.postimg.cc/5y8cqrRs/Capture-d-cran-2025-03-06-135320.jpg

You see ? You have several action buttons (which appear depending on the status of the order). By clicking on an action, it opens a modal with a different form.

Like this one : https://i.postimg.cc/1Xm0JnWb/Capture-d-cran-2025-03-06-135538.jpg

For your test :

//Similar to yours.
it('can view an order', function () {
    $this->get(OrderResource::getUrl('view', [
        'record' => Order::factory()->create(),
    ]))->assertSuccessful();
});

Passed : https://i.postimg.cc/3J0nkpvx/Capture-d-cran-2025-03-06-135025.jpg

And here the failed tests on my local environment :

https://i.postimg.cc/0NZy7zwz/Capture-d-cran-2025-03-06-135758.jpg

Here you can see 2 tests fail because it cannot find the model.

So, here the 2 tests :

What I don't understand at all is that it isn't consistent! For example, in the screenshot below, I ran the test for the first time: it failed. I ran it a second time without changing anything: it passed!

https://i.postimg.cc/DzspJG4T/Capture-d-cran-2025-03-06-140431.jpg

newbie360's avatar

@Vable your tests look like unit test more than feature test

what about this

it('can change order status via action', function () {
    $order = Order::factory()->create(['status' => Status::TO_ORDER]);

    $component = livewire(ViewOrder::class, [
        'record' => $order->getRouteKey()
    ]);

    $component
        ->callAction('the-modal-action-name', $order)
        ->fillForm([
            'status' => Status::IN_ORDER,
        ])
        ->call('save')
        ->assertHasNoFormErrors();

    expect($order->refresh())
        ->status->toBe(Status::IN_ORDER);
});

you may to think refactor this code to a function instead of in every test repeat this, make it more readable and reduce the lines count

    $order = Order::factory()->create(['status' => Status::TO_ORDER]);

    $component = livewire(ViewOrder::class, [
        'record' => $order->getRouteKey()
    ]);
Lopsum's avatar
Level 5

It is true that after gathering a bit of information, it is very limited to a page and its processing, which means it isn't really a feature if I understood well... However, with or without refactoring, the problem remains the same 😞

Please or to participate in this conversation.