- When needing HTTP testing in code, Laravel has built-in functionality for this. With Slim, we have to build our own solution.
- After searching online for examples and finding limited resources, I decided to examine Laravel’s source code for inspiration.
- Discovered that the core idea is to mock a Request object and execute it to get response results.
- Implemented this approach in Slim framework accordingly.
Setting Up Test Files
- Add autoload configuration in
composer.json
and run composer dump-auto
:
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
- Create
phpunit.xml
at root directory:
<phpunit bootstrap="tests/bootstrap.php">
<testsuites>
<testsuite name="Feature">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
</phpunit>
- Create
tests/bootstrap.php
with content:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
$name = $args['name'];
$response->getBody()->write("Hello, $name");
return $response;
});
$app->get('/api/v1/users', function (Request $request, Response $response) {
$data = [['name' => 'Bob', 'age' => 40]];
$payload = json_encode($data);
$response->getBody()->write($payload);
return $response
->withHeader('Content-Type', 'application/json');
});
// Do not run the app here
// $app->run();
function getApplication()
{
global $app;
return $app;
}
- Create test file
tests/HomeTest.php
:
<?php
namespace Tests;
use Nyholm\Psr7\Uri;
use PHPUnit\Framework\TestCase;
use Slim\Factory\ServerRequestCreatorFactory;
class HomeTest extends TestCase
{
public function testHello()
{
$name = 'Bob';
$serverRequestCreator = ServerRequestCreatorFactory::create();
$request = $serverRequestCreator->createServerRequestFromGlobals();
$uri = new Uri();
$request = $request->withUri($uri->withPath("/hello/{$name}"));
$response = getApplication()->handle($request);
$responseContent = (string)$response->getBody();
$this->assertEquals("Hello, {$name}", $responseContent);
}
public function testJsonApi()
{
$serverRequestCreator = ServerRequestCreatorFactory::create();
$request = $serverRequestCreator->createServerRequestFromGlobals();
// Uri and Request objects are immutable - create new instances
$uri = new Uri();
$request = $request->withUri($uri->withPath('api/v1/users'));
// For fake query parameters:
// $request = $request->withQueryParams([]);
$response = getApplication()->handle($request);
$responseContent = (string)$response->getBody();
$this->assertJson($responseContent);
}
}
- Finally, execute tests with PHPUnit:
$ phpunit
PHPUnit 7.5.17 by Sebastian Bergmann and contributors.
.. 2 / 2 (100%)
Time: 45 ms, Memory: 4.00 MB
OK (2 tests, 2 assertions)