Handling Large Payload for Testing API

October 22, 2021
Generating test suite payload of large API can be mind-numbing if not implemented properly. Let us take a look on how to handle this in the best possible way.

In this example, I am using Laravel for backend and Pest PHP for testing. This is the sample route and payload:


Route::post('submit', function(\Illuminate\Http\Request $request){
    ray($request->all());
})->name('submit');


{
  "first_name": "Lloric",
  "last_name": "garcia",
  "hobbies": [
    "programming",
    "gaming"
  ],
  "products": [
    {
      "id": "p1",
      "quantity": 1
    },
    {
      "id": "p2",
      "quantity": 2
    }
  ]
}

Here is the typical API test suite:


it('submit to api', function(){
    \Pest\Laravel\post(route('submit'),[
        'first_name' => 'Lloric',
        'last_name' => 'garcia',
        'hobbies' => [
            'programming',
            'gaming',
        ],
        'products' => [
            [
                'id' => 'p1',
                'quantity' => 1
            ],
            [
                'id' => 'p2',
                'quantity' => 2
            ]
        ]
    ])
        ->assertValid();
});

Result in ray debugger

Now, let us assume that the example above has large API payload. Repeating that payload multiple times is a tiresome task therefore we will create a reusable function to make this code maintainable.

For this use case, we will make a class called MySubmitPayloadTestFactory. (note: This is what I learned from Spatie Testing Laravel Course. Here is the reference episode to learn more.)


namespace Tests\Factories;

use Illuminate\Testing\TestResponse;

use function Pest\Laravel\post;

final class MySubmitPayloadTestFactory
{
    // this is better, when dealing with Model
    private string $firstName;
    private string $lastName;

    /** @var array */
    private array $hobbies = [];

    /** @var array  > */
    private array $product = [];

    private function __construct()
    {
    }

    public static function make(): self
    {
        return new self();
    }

    public function firstName(string $firstName): self
    {
        $this->firstName = $firstName;
        return $this;
    }

    public function lastName(string $lastName): self
    {
        $this->lastName = $lastName;
        return $this;
    }

    public function addHobbies(string $hobby): self
    {
        $this->hobbies[] = $hobby;
        return $this;
    }

    public function addProduct(string $product, int $quantity = 1): self
    {
        $this->product[] = [
            'id' => $product,
            'quantity' => $quantity,
        ];
        return $this;
    }

    public function runPost(): TestResponse
    {
        return post(route('submit'), $this->generatePayload());
    }

    private function generatePayload(): array
    {
        return [
            'first_name' => $this->firstName,
            'last_name' => $this->lastName,
            'hobbies' => $this->hobbies,
            'products' => $this->product,
        ];
    }
}

This is the updated test suite using the factory that we made:


it('submit to api v2', function () {

    \Tests\Factories\MySubmitPayloadTestFactory::make()

        ->firstName('Lloric')
        ->lastName('garcia')

        ->addHobbies('programming')
        ->addHobbies('gaming')

        ->addProduct('p1')
        ->addProduct('p2', 2)

        ->runPost()
        ->assertValid();
});

Here is the before and after test suite:


it('submit to api', function () {
    \Pest\Laravel\post(route('submit'), [
        'first_name' => 'Lloric',
        'last_name' => 'garcia',
        'hobbies' => [
            'programming',
            'gaming',
        ],
        'products' => [
            [
                'id' => 'p1',
                'quantity' => 1,
            ],
            [
                'id' => 'p2',
                'quantity' => 2,
            ],
        ],
    ])
        ->assertValid();
});

it('submit to api v2', function () {

    \Tests\Factories\MySubmitPayloadTestFactory::make()

        ->firstName('Lloric')
        ->lastName('garcia')

        ->addHobbies('programming')
        ->addHobbies('gaming')

        ->addProduct('p1')
        ->addProduct('p2', 2)

        ->runPost()
        ->assertValid();
});

Good luck! Tweet me and share with me what you’ve been able to create!