Slim 3 Integration Test For POST Method Always Not Included Header

I’m currently developing an application written using Slim 3 framework, and trying to use the TDD concept, but I’m facing several issues, including when using the test for the POST method, the headers that I embed are always considered missing.

Below is my code

<?php

namespace Tests\routes\shopify;

use PHPUnit\Framework\TestCase;
use Slim\App;
use Slim\Http\Environment;
use Slim\Http\Headers;
use Slim\Http\Request;
use Slim\Http\RequestBody;
use Slim\Http\Response;
use Slim\Http\UploadedFile;
use Slim\Http\Uri;

class ShopifyRoutesTest extends TestCase
{
    private $app;

    protected function setUp(): void
    {
        // Use the application settings
        $settings = require __DIR__ . '/../../../src/settings.php';

        // Instantiate the application
        $this->app = new App($settings);

        // Set up dependencies
        $dependencies = require __DIR__ . '/../../../src/dependencies.php';
        $dependencies($this->app);

        // Register middleware
        $middleware = require __DIR__ . '/../../../src/middleware.php';
        $middleware($this->app);

        // Register routes
        $routes = require __DIR__ . '/../../../src/app/routes/api/shopify/routes.php';
        $routes($this->app);
    }

    public function testPostSyncProductBySkuWithEmptyApikeyShouldReturnBadRequest()
    {
        // Create a mock environment for testing with
        $environment = Environment::mock();
        $uri = Uri::createFromString("/channel/shopify/v1/product/sync-by-sku");
        $headers = new Headers(array(
            "Content-Type" => "application/json",
            "Authorization" => "client-apikey",
            "x-api-key" => ""
        ));
        $cookies = [];
        $serverParams = $environment->all();
        $body = new RequestBody();
        $uploadedFiles = UploadedFile::createFromEnvironment($environment);

        // Set up a request object based on the environment
        $request = new Request("POST", $uri, $headers, $cookies, $serverParams, $body, $uploadedFiles);

        $reqBody = array(
            "shop_name" => "STORE ABCE",
            "sku" => "SKU-001"
        );

        $body->write(json_encode($reqBody));


        // Add request data, if it exists
        $request = $request->withParsedBody($reqBody);
        // Set up a response object
        $response = new Response();

        $response = $this->app->process($request, $response);

        self::assertEquals(400, $response->getStatusCode());
        self::assertStringContainsString("Header: x-api-key cannot be empty", $response->getBody());
    }

    protected function tearDown(): void
    {
        $this->app = null;
    }
}


the first assertion succeeds with a value of 400, but in the second assertion its fails, the string doesn’t contain the value “Header: x-api-key cannot be empty” but instead this

Failed asserting that '{\n
    "error": "AUTH_FAIL",\n
    "errorDetail": "Header: Authorization, x-api-key required",\n
    "status": 400,\n
    "message": "BAD_REQUEST",\n
    "data": ""\n
}' contains "Header: x-api-key cannot be empty".

the strange thing is that when I var_dump($request->getHeaders()) the headers value of the request I made it turns out to be there

array(3) {
  ["Content-Type"]=>
  array(1) {
    [0]=>
    string(16) "application/json"
  }
  ["Authorization"]=>
  array(1) {
    [0]=>
    string(13) "client-apikey"
  }
  ["x-api-key"]=>
  array(1) {
    [0]=>
    string(0) ""
  }
}

I’ve also tried testing my API endpoint using Postman, and the results are as expected

Request

curl --location --request POST 'http://localhost:8080/channel/shopify/v1/product/sync-by-sku' \
--header 'Authorization: client-apikey' \
--header 'x-api-key: 1293129382938' \
--header 'Content-Type: application/json' \
--header 'Cookie: PHPSESSID=tll8s24tp253rda1harv0koapi' \
--data-raw '{
    "shop_name" : "STORE ABC",
    "sku" : "SKU-991"
}'

Response

{
    "error": "AUTH_FAIL",
    "errorDetail": "Header: x-api-key cannot be empty",
    "status": 400,
    "message": "BAD_REQUEST",
    "data": ""
}

Also I’ve read the answer from stakoverflow as described here Mock Slim endpoint POST requests with PHPUnit

But still I can’t find the solution, the header is always presumed to be missing. I really appreciate the solution to this problem, thank you in advance

Have you tried this in order to make the middleware work?

$response = $this->app->process($request, $response);