0

I'm working on a Laravel application with authentication. The application also has an API. Now I want to test all the API endpoints of the application. The Problem is, that the some Endpoints Need data in the database to "work" with.

How is it possible to test such an application? Do I have to test the application in the correct order to achieve something like that?

For example:

  1. create user
  2. create new post
  3. edit new post
  4. create new user
  5. comment post of user 1
  6. login with user 1
  7. see comments of post
  8. delete post

Or is it possible to simulate stuff like this so I don't need a specific order?

I saw that Laravel has build in HTTP testing, but I don‘t know how to handle the data dependencies.

halfer
  • 19,824
  • 17
  • 99
  • 186
Mike_NotGuilty
  • 2,253
  • 5
  • 32
  • 64

1 Answers1

1

You can define Factory for creating your models. https://laravel.com/docs/5.8/database-testing#writing-factories For example in our project we have lot's of Factories. They describe how to create model. enter image description here

And later in your test code you just call $partner = factory(Partner::class)->create() In order to create model.

    public function testUpdate(): void
{
    /** @var Partner $partner */
    $partner = factory(Partner::class)->create();
    $name = 'Fake Partner';
    $description = 'Fake Partner Description';

    $response = $this->putJson('/partners/' . $partner->uuid, [
        'name' => $name,
        'description' => $description,
    ]);
}

For making action via user you can user actingAs($user)->get( https://laravel.com/docs/5.2/testing#sessions-and-authentication

If your user required any other references to others 'Entities' You can create them right in the definition in your user factory.

$factory->define(User::class, static function (Faker $faker) {
    return [
        'organization_id' => factory(Organization::class),
        'name' => $faker->word,
        'description' => $faker->words(3, true),
    ];
});
112Legion
  • 1,129
  • 12
  • 25
  • does `->create()` Store something in the database or does it just „simulate“ everything? Because then I need to delete everything after the test? – Mike_NotGuilty Jan 29 '20 at 15:05
  • `create()` does save data to database. Use `make()` if you don't need to save data to database. – 112Legion Jan 29 '20 at 15:06
  • 1
    @Mike_NotGuilty laravel trait `\Illuminate\Foundation\Testing\DatabaseTransactions` begin transaction before each test and call rollback after it finished. So you don't need to delete anything manually. – 112Legion Jan 29 '20 at 15:08
  • That sounds great, I will try it asap! I have one more question: I have some Kind of basic setup (database entries) that I Need for every test. Is it possible to define them, so I can access them in all my tests? Thanks! – Mike_NotGuilty Jan 30 '20 at 13:04
  • For example: A User has a field „organization“ - this can‘t be null.. so I would have to create a organization First every test! Which sounds like serious pain to me – Mike_NotGuilty Jan 30 '20 at 13:10
  • @Mike_NotGuilty I have updated answer. Check it out. – 112Legion Jan 30 '20 at 14:30
  • 1
    @Mike_NotGuilty it would be nice but I don't insist if you upvote my answer if you think it was helpful. – 112Legion Jan 30 '20 at 18:38
  • Everything works fine!! sorry for the late answer... But now I have one more question. I want to test every test as admin and user - Users should sometimes not be able to edit/create/delete something -> Status 403. Is it possible to automate this ore do I need to write every test twice? – Mike_NotGuilty Mar 15 '20 at 14:34
  • @Mike_NotGuilty You will need to write every test twice like so testForbiddenWhenUserDeleteSomething. But I recommend to write only positive scenarios "admin can delete". First of all you should know the important of security of the part if you are working on payment system subscription you probably should cover as mush cases as you can (otherwise your company might lose money) in other cases such as deleting or editing comments won't have much affect on business. Ask your manager "do we need extra security check here to cover all possible scenario?". – 112Legion Mar 16 '20 at 07:25
  • @Mike_NotGuilty but to cover several roles do not have access to the same route ('user', 'manager', etc) you could use DataProvider PhpUnit annotation https://phpunit.readthedocs.io/en/9.0/annotations.html#dataprovider – 112Legion Mar 16 '20 at 07:32