1
votes

I do not understand what happens on an API test (laravel 8).

This call (a very simple put) returns a response 200 , using postman.

enter image description here

The same test using phpunit, returns 201 :

public function testPutOrganizationOk()
{
    $organization = Organization::factory()->create();

    $superAdmin = User::factory()->create([
        'organization_id' => $organization->id,
        'role_id' => 'SUPERADMIN'
    ]);

    Sanctum::actingAs($superAdmin);

    $organizationToModify = [
        'name' => 'mon organization moif',
        'contact' => 'contact name modif',
        'comment' => 'comment comment comment modif',
        'ads_max' => 12345,
        'state_id' => 'VALIDATED'
    ];

    $response = $this->putJson($this->getUrl() . '/organizations/' . $organization->id, $organizationToModify);

    $response->assertStatus(200);
}

The error is :

  1. Tests\Feature\OrganizationTest::testPutOrganizationOk Expected status code 200 but received 201. Failed asserting that 200 is identical to 201.

I tried a lot of things , without success. I really do not understand what happens. Any suggestions will be appreciated. Thanks.

EDIT :my controller

public function update(StoreOrganizationRequest $request, Organization $organization)
    {
        $this->authorize('update', Organization::class);

        $organizationUpdated = $this->organizationRepository->updateOrganization($organization, $request->only(['name', 'contact', 'comment', 'ads_max', 'state_id']));

        return new OrganizationResource($organizationUpdated);
    }

EDIT 7 hours later ;-)

When I replace , in the controller, the return of the resource by a return of a simple json, then I have the same behaviour between postman and phpunit . The api call receives a 200 for the update.

Strange, it means that the problem is around the resource ?

Why a different behavior between postman and phpunit ? Who is right : postman or phpunit ?

3
putJson instead of put :) - Kurt Friars
I tried a lot of things : $this->json('PUT'.... , but also $this->put, and also $this->putJson. And each time I have the same 201 instead of 200. But thanks for your help. - Dom
In your organizations controller, try specifying the response code? - Kurt Friars
Please can you show your controller code. Are you using a Resource class? - Rwd
I just read this topic laraveldaily.com/… which explains that : Notice that if we don’t specify the status code for return, Laravel will do it automatically for us, and that may be incorrect. So it is advisable to specify codes whenever possible. - Dom

3 Answers

0
votes

The http code 201, it mean created success. see here developer.mozilla.org

and you able to customize the header code by:

return Response::json(new OrganizationResource($organizationUpdated), 200);
0
votes

201 Status Code says that you just create an Instance, and 200 Status Code says that already existing Instance has been update

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI."

I might be wrong but seems like you have created the instance first and trying to modifying it then

0
votes

Finally, I give up!

I will write the response with a status code like that:

return (new OrganizationResource($organization))->response()->setStatusCode(200);

instead of:

return new OrganizationResource($organization);

it's longer to write, but at least my tests are OK.