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

ssquare's avatar

Laravel testing assertJSONStructure is passing even when it should have failed

This is the sample of response I received on ajax:

data: [
	{
		action: "some string",
		id: 1,
		price: 399,
		service_name: "Get a Domain",
		title: "BASIC",
	},
	{...},
	{...}
	]
draw: 1
recordsFiltered: 21
recordsTotal: 21

and my test for this is:

class PackageTest extends TestCase
{
    use RefreshDatabase, WithFaker, DatabaseMigrations;
    protected $endPoint = '/dashboard/packages';

    /**========================
     * Should Pass Test Case *
    =========================*/
    public function test_packages_list_showing_correctly()
    {
        $this->signIn();
        $resp = $this->ajaxGet($this->endPoint)
            ->assertStatus(Response::HTTP_OK)
            ->assertJsonStructure([
                'data' => [
                    '*' => [
                        'xid',
                        'xtitle',
                        'xprice',
                        'xservice_name'
                    ]
                ],
            ]);
    }
}

Actually, this should have been failed but surprisingly it is being passed. What am I doing wrong here? or from where should I start debugging it.

But, this one is failing, because of xdata

            ->assertJsonStructure([
                'xdata' => [
                    '*' => [
                        'xid',
                        'xtitle',
                        'xprice',
                        'xservice_name'
                    ]
                ],
            ]);

By the way, if you are curious what does those signin() and ajaxGet(), then here is the code of that:

protected function signIn($user = null)
{
    $user = $user ?: User::factory()->create(['role_id' => Role::factory()->create(['name' => 'superAdmin'])]);
    $this->actingAs($user, 'web');
    return $user;
}

public function ajaxGet($uri)
{
    return $this->get($uri, ['HTTP_X-Requested-With' => 'XMLHttpRequest']);
}
0 likes
9 replies
SilenceBringer's avatar

@ssquare I think it's because you have an empty data in response, like:

data: []
draw: 1
recordsFiltered: 0
recordsTotal: 0

so, it can't really checke what data item looks like

Of course it fales on xdata, because data presented in response

ssquare's avatar

At first, I think that before every test the database is empty because I have used

use RefreshDatabase, WithFaker, DatabaseMigrations;

but I tried creating .env.testing and after running seeder on it and run this, but still, it is getting passed, which means it is still passing when not empty.

But still, should I assert anything else?

Any suggestion, I just want to test if those fields are present on the data array inside every object.

ssquare's avatar

Okay, I got the point, so before this test, I have to create one first?? Or is there some better way, to deal situation like this?

tykus's avatar

I don't get it; where were you running the seeder before?

In the Test example, you can use Model Factories to put data (relevant to the test example) into the database; similar to your signin method which creates a User from a Factory, you can do the same for Packages.

tykus's avatar

But still, should I assert anything else?

You can first assert that there is something in the data key:

$resp = $this->ajaxGet($this->endPoint)
	->assertStatus(Response::HTTP_OK)
	->assertJsonCount(1, 'data') // change 1 for expected number
	->assertJsonStructure([/* the structure */]);

This will guarantee there is something in data against which to make assertions about structure

ssquare's avatar

Thank you tykus, instead of counting exactly one, can I assert if there is at least one with no upper limit.

tykus's avatar

Try not to be fuzzy about your test assertions; if you arrange the world in a particular way, then act on that world; you can assert against known outcomes; i.e. add exactly N packages to the database which you should expect to be returned from the endpoint; then assert that there are N packages in the data key.

2 likes

Please or to participate in this conversation.