Testing Your API

Automated testing is essential to ensure your API works as expected and keeps working as you add features. LacePHP provides a simple Tester class that simulates HTTP requests against your routes, so you can write quick, readable tests without spinning up an external client or server.

Why Testing Matters

  • Confidence: Catch regressions early when you change code.

  • Documentation: Tests show exactly how your API should behave.

  • Speed: Run hundreds of route tests in seconds without a real HTTP server.

Introducing Tester

The LaceboxSoleHeelTester class gives you a fluent DSL:

namespace Tests;

use Lacebox\Sole\Heel\Tester;
use Lacebox\Sole\Router;

// Create a tester with your app’s router
$router = require __DIR__ . '/../routes/api.php';
$t      = new Tester($router);

// Simulate a GET request, check status and JSON
$t->get('/posts')
  ->expect(200)
  ->json([
      ['id'=>1, 'title'=>'First post'],
      ['id'=>2, 'title'=>'Second post'],
  ]);

Key Methods

  • get(string $uri): self - Simulate GET $uri.

  • expect(int $code): self - Assert the HTTP status code (e.g. 200, 404).

  • json(array $expected): self - Decode the response body as JSON and compare strictly to $expected.

  • raw(): mixed - Retrieve the raw response (string or array) for custom assertions.

Basic Example

Test the POST /login endpoint returns a token:

<?php
// tests/LoginTest.php

use Lacebox\Sole\Heel\Tester;
use function sole_request;

$router = require __DIR__ . '/../routes/api.php';
$t = new Tester($router);

$t->get('/login?user=alice&pass=secret')
  ->expect(200)
  ->json([
      'token' => 'abc123def456'
  ]);

Checking Error Responses

You can also assert non-200 codes:

$t->get('/posts/9999')
  ->expect(404)
  ->raw();  // inspect body or leave as is

Combining Multiple Requests

Chain multiple scenarios in one script:

// tests/PostCrudTest.php

$t->get('/posts')->expect(200)->json([/* all posts */]);

$t->get('/posts/1')->expect(200)->json([
    'id' => 1,
    'title' => 'First post',
]);

$t->get('/posts/999')->expect(404);

Best Practices

  • Isolate your data: run tests against an in-memory or test database.

  • Reset state: truncate tables or use dummy transactions.

  • Group assertions: one test file per resource or feature.

  • Use descriptive names: comments or method names explain each scenario.

Warning

  • Tester manipulates $_SERVER, REQUEST_URI and http_response_code(); avoid mixing with real server calls.

  • Tests run synchronously in PHP, avoid long-running tasks or external HTTP calls inside your routes.

  • If your route uses session or CSRF, initialise or disable those protections in your test bootstrap.

By using LacePHP’s Tester, you can write clear, fast route tests—making their APIs reliable and easy to maintain.