원클릭으로
horse-integration-tests
Guide for writing automated integration tests for Horse endpoints using DUnit/DUnitX and THTTPClient.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Guide for writing automated integration tests for Horse endpoints using DUnit/DUnitX and THTTPClient.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Guidelines and workflows for developing and maintaining regular expressions and optional parameter routing features in the Horse framework.
Guidelines for registering, executing, and optimizing native high-precision telemetry hooks (AddOnTelemetry) in the Horse Web Framework.
Guidelines for instantiating and configuring independent Horse server instances (THorseInstance) running concurrently on different ports.
Guide for setting up thread-safe database connection pooling (FireDAC / UniDAC) in multithreaded Horse applications.
Guide for managing request-scoped contextual services and IoC (dependency injection) in Delphi and Lazarus.
Guide to using standard Horse middlewares (CORS, Jhonson, compression, basic-auth, logger) and pipeline registration order.
| name | horse-integration-tests |
| description | Guide for writing automated integration tests for Horse endpoints using DUnit/DUnitX and THTTPClient. |
Automated integration tests ensure your API routes, request parsing, and error-handling pipelines behave correctly under simulated HTTP traffic.
When running tests locally or in CI/CD pipelines (like GitHub Actions), static ports (e.g., 9000) might be occupied. To avoid port conflicts:
http://localhost:<dynamic_port>.Here is a complete integration test suite demonstrating how to bootstrap Horse, perform requests with Delphi's native THTTPClient, and assert responses:
unit Test.UserAPI;
interface
uses
DUnitX.TestFramework,
System.Net.HttpClient,
System.SysUtils;
type
[TestFixture]
TTestUserAPI = class
private
FPort: Integer;
FClient: THTTPClient;
function GetBaseURL: string;
public
[SetupFixture]
procedure SetupFixture; // Start Horse Server
[TearDownFixture]
procedure TearDownFixture; // Terminate Horse Server
[Setup]
procedure Setup;
[TearDown]
procedure TearDown;
[Test]
procedure TestGetPingReturnsPong;
[Test]
procedure TestGetInvalidUserReturns404;
end;
implementation
uses
Horse,
System.JSON,
System.Net.URLClient;
function TTestUserAPI.GetBaseURL: string;
begin
Result := 'http://localhost:' + FPort.ToString;
end;
procedure TTestUserAPI.SetupFixture;
begin
// Choose a random dynamic port
Randomize;
FPort := 10000 + Random(50000);
// Register endpoints to test
THorse.Get('/ping',
procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)
begin
Res.Send('pong');
end);
THorse.Get('/users/:id',
procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)
var
LId: Integer;
begin
LId := Req.Params.Field('id').AsInteger;
if LId = 999 then
Res.Status(THTTPStatus.NotFound).Send('User not found')
else
Res.Send('User found');
end);
// Start Horse asynchronously (non-blocking)
THorse.Listen(FPort);
end;
procedure TTestUserAPI.TearDownFixture;
begin
// Terminate the process / stop Horse provider
THorse.Terminate;
end;
procedure TTestUserAPI.Setup;
begin
FClient := THTTPClient.Create;
end;
procedure TTestUserAPI.TearDown;
begin
FClient.Free;
end;
procedure TTestUserAPI.TestGetPingReturnsPong;
var
LResponse: IHTTPResponse;
begin
LResponse := FClient.Get(GetBaseURL + '/ping');
Assert.AreEqual(200, LResponse.StatusCode);
Assert.AreEqual('pong', LResponse.ContentAsString);
end;
procedure TTestUserAPI.TestGetInvalidUserReturns404;
var
LResponse: IHTTPResponse;
begin
LResponse := FClient.Get(GetBaseURL + '/users/999');
Assert.AreEqual(404, LResponse.StatusCode);
Assert.AreEqual('User not found', LResponse.ContentAsString);
end;
initialization
TDUnitX.RegisterTestFixture(TTestUserAPI);
end.
Controller units. Do not define routes inline in your test project setup unless you are testing general configuration middleware behavior.THorse.Terminate: Failing to call Terminate in your tear down fixture will leave the TCP socket open, preventing subsequent test executions from binding to the same port.