一键导入
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.