Pular para o conteúdo principal

Mock Testing

RestServer provides robust mock testing capabilities that allow you to test your API endpoints without making actual HTTP requests.

Mock Request Handler

The MockRequestHandler class provides a way to simulate HTTP requests to your API and get back the response that would be generated.

Basic Example

<?php
use ByJG\RestServer\MockRequestHandler;
use ByJG\RestServer\Route\RouteList;
use Nyholm\Psr7\Request;

// Define your routes
$routeDefinition = new RouteList();
$routeDefinition->addClass(MyApiController::class);

// Create a mock PSR-7 request
$request = new Request(
'GET',
'/api/products/123',
['Accept' => 'application/json']
);

// Create a mock handler
$mockHandler = MockRequestHandler::mock($routeDefinition, $request);

// Get the response
$statusCode = $mockHandler->getPsr7Response()->getStatusCode();
$headers = $mockHandler->getPsr7Response()->getHeaders();
$body = $mockHandler->getPsr7Response()->getBody()->getContents();

// Now you can make assertions on the response

Mock HTTP Request

The MockHttpRequest class extends HttpRequest to allow testing with simulated parameters:

<?php
use ByJG\RestServer\MockHttpRequest;
use Nyholm\Psr7\Request;

// Create a PSR-7 request
$psr7Request = new Request('POST', '/api/users');

// Create a mock request with simulated parameters
$mockHttpRequest = new MockHttpRequest($psr7Request, [
"id" => 123,
"name" => "John Doe",
"email" => "[email protected]"
]);

// Use the mock request for testing
$id = $mockHttpRequest->param("id"); // Returns 123

Mock Response

The MockResponse class helps capture and examine responses:

<?php
use ByJG\RestServer\MockResponse;
use ByJG\RestServer\OutputProcessor\JsonOutputProcessor;

// In test scenarios, you can handle exceptions with mock responses
try {
// Code that might throw an exception
doSomethingThatThrows();
} catch (Exception $ex) {
// Create a mock error response
$result = MockResponse::errorHandlerFromEndpoint(
$ex,
new JsonOutputProcessor(),
$routeDefinition,
'GET',
'/api/resource'
);

// Examine the raw JSON returned by the error handler
$this->assertJsonStringEqualsJsonString('{"error": "Not Found"}', $result);
}

Building reusable test harnesses

Larger test suites benefit from a reusable helper that hides the boilerplate of instantiating MockRequestHandler and creating PSR-7 requests. The following trait shows one way to structure that helper:

<?php
namespace Tests\Support;

use ByJG\RestServer\MockRequestHandler;
use ByJG\RestServer\OutputProcessor\JsonOutputProcessor;
use ByJG\RestServer\Route\Route;
use ByJG\RestServer\Route\RouteList;
use Nyholm\Psr7\Request;
use Psr\Http\Message\ResponseInterface;

trait ApiTestTrait
{
protected RouteList $routes;

protected function bootRoutes(): void
{
$this->routes = new RouteList();
$this->routes->addRoute(
Route::get('/api/resource')
->withClosure(function ($response, $request) {
$response->write(['status' => 'success']);
})
);
}

protected function request(string $method, string $path, array $headers = [], ?string $body = null): ResponseInterface
{
$psr7Request = new Request($method, $path, $headers, $body);
$handler = new MockRequestHandler();
$handler
->withDefaultOutputProcessor(JsonOutputProcessor::class)
->withRequestObject($psr7Request)
->handle($this->routes);
return $handler->getPsr7Response();
}
}
<?php
use PHPUnit\Framework\TestCase;
use Tests\Support\ApiTestTrait;

class MyApiTest extends TestCase
{
use ApiTestTrait;

protected function setUp(): void
{
$this->bootRoutes();
}

public function testGetEndpoint(): void
{
$response = $this->request('GET', '/api/resource');
$this->assertSame(200, $response->getStatusCode());
$this->assertJsonStringEqualsJsonString('{"status":"success"}', (string) $response->getBody());
}
}
Reference implementation

The repository’s own test suite includes tests/MockServerTrait.php, demonstrating a more elaborate setup with pre-registered routes, middlewares, and error handling hooks. Feel free to adapt that trait inside your project if you need heavier integration fixtures.

Benefits of Mock Testing

  • Test API endpoints without running a web server
  • Fast execution of tests without network overhead
  • Simulate various request scenarios (parameters, headers, body)
  • Test error handling and exception cases
  • Fully integrated with PHPUnit and other testing frameworks

By using these mock testing capabilities, you can ensure your API works correctly before deploying it to production.