Files
dyp/pas/uUnitTests.pas
2026-05-07 20:25:34 +08:00

813 lines
22 KiB
ObjectPascal

unit uUnitTests;
interface
uses
TestFramework, SysUtils, Classes, System.JSON, uExceptionHandler, uLogManager,
uConfigManager, uBusinessServices, uCommonUtils;
type
TTestExceptionHandler = class(TTestCase)
published
procedure TestBaseException;
procedure TestNetworkException;
procedure TestDataException;
procedure TestBusinessException;
procedure TestDeviceException;
procedure TestValidationException;
procedure TestExceptionHandler;
end;
TTestLogManager = class(TTestCase)
published
procedure TestLogLevels;
procedure TestLogCategories;
procedure TestPerformanceLogger;
procedure TestLogExport;
procedure TestUIMonitoring;
procedure TestNetworkMonitoring;
procedure TestFormMonitoring;
procedure TestDataOperationMonitoring;
procedure TestLogCategoriesFilter;
end;
TTestConfigManager = class(TTestCase)
published
procedure TestConfigLoading;
procedure TestConfigSaving;
procedure TestConfigTypes;
procedure TestAppConfig;
procedure TestAppConfigExtended;
procedure TestConfigArrayAndObject;
end;
TTestBusinessServices = class(TTestCase)
published
procedure TestAuthService;
procedure TestAuthServiceLogout;
procedure TestAuthServiceRefreshToken;
procedure TestWorkOrderService;
procedure TestWorkOrderServiceCreate;
procedure TestWorkOrderServiceUpdateStatus;
procedure TestWorkOrderServiceReportProduction;
procedure TestDeviceService;
procedure TestDeviceServiceConnectDisconnect;
procedure TestDeviceServiceSendCommand;
procedure TestSyncService;
procedure TestSyncServiceBatch;
procedure TestSyncServiceRetry;
procedure TestProductionReportingService;
procedure TestProductionReportingServiceValidateUser;
procedure TestProductionReportingServiceGetWorkOrderInfo;
procedure TestProductionReportingServiceGetProcessList;
procedure TestProductionReportingServiceValidateGoodsNo;
procedure TestProductionReportingServiceSubmitData;
procedure TestDeviceConfigService;
procedure TestDataAccessService;
end;
TTestCommonUtils = class(TTestCase)
published
procedure TestValidator;
procedure TestStringHelper;
procedure TestDateTimeHelper;
procedure TestFileHelper;
procedure TestJSONHelper;
end;
implementation
{ TTestExceptionHandler }
procedure TTestExceptionHandler.TestBaseException;
var
Ex: EBaseException;
JSON: TJSONObject;
begin
Ex := EBaseException.Create('Test exception', 1001, 'Test');
try
CheckEquals('Test exception', Ex.Message);
CheckEquals(1001, Ex.ErrorCode);
CheckEquals('Test', Ex.ErrorType);
JSON := Ex.ToJSON;
try
CheckNotNull(JSON);
CheckEquals('Test exception', JSON.GetValue('message').Value);
finally
JSON.Free;
end;
finally
Ex.Free;
end;
end;
procedure TTestExceptionHandler.TestNetworkException;
var
Ex: ENetworkException;
begin
Ex := ENetworkException.Create('Network error', 2001);
try
CheckEquals('Network error', Ex.Message);
CheckEquals(2001, Ex.ErrorCode);
CheckEquals('Network', Ex.ErrorType);
finally
Ex.Free;
end;
end;
procedure TTestExceptionHandler.TestDataException;
var
Ex: EDataException;
begin
Ex := EDataException.Create('Data error', 3001);
try
CheckEquals('Data error', Ex.Message);
CheckEquals(3001, Ex.ErrorCode);
CheckEquals('Data', Ex.ErrorType);
finally
Ex.Free;
end;
end;
procedure TTestExceptionHandler.TestBusinessException;
var
Ex: EBusinessException;
begin
Ex := EBusinessException.Create('Business error', 4001);
try
CheckEquals('Business error', Ex.Message);
CheckEquals(4001, Ex.ErrorCode);
CheckEquals('Business', Ex.ErrorType);
finally
Ex.Free;
end;
end;
procedure TTestExceptionHandler.TestDeviceException;
var
Ex: EDeviceException;
begin
Ex := EDeviceException.Create('Device error', 5001);
try
CheckEquals('Device error', Ex.Message);
CheckEquals(5001, Ex.ErrorCode);
CheckEquals('Device', Ex.ErrorType);
finally
Ex.Free;
end;
end;
procedure TTestExceptionHandler.TestValidationException;
var
Ex: EValidationException;
begin
Ex := EValidationException.Create('Field', 'Value', 'Validation error');
try
CheckEquals('Validation error', Ex.Message);
CheckEquals('Field', Ex.FieldName);
CheckEquals('Value', Ex.FieldValue);
finally
Ex.Free;
end;
end;
procedure TTestExceptionHandler.TestExceptionHandler;
var
Handler: TExceptionHandler;
Ex: Exception;
begin
Handler := TExceptionHandler.Create;
try
Ex := Exception.Create('Test exception');
try
Handler.HandleException(Ex);
// 验证没有异常抛出
finally
Ex.Free;
end;
finally
Handler.Free;
end;
end;
{ TTestLogManager }
procedure TTestLogManager.TestLogLevels;
begin
LogManager.Trace('Test trace');
LogManager.Debug('Test debug');
LogManager.Info('Test info');
LogManager.Warn('Test warn');
LogManager.Error('Test error');
LogManager.Fatal('Test fatal');
// 验证没有异常抛出
end;
procedure TTestLogManager.TestLogCategories;
begin
LogManager.TraceCategory(lcSystem, 'Test system');
LogManager.DebugCategory(lcNetwork, 'Test network');
LogManager.InfoCategory(lcDatabase, 'Test database');
LogManager.WarnCategory(lcBusiness, 'Test business');
LogManager.ErrorCategory(lcDevice, 'Test device');
LogManager.FatalCategory(lcUI, 'Test UI');
// 验证没有异常抛出
end;
procedure TTestLogManager.TestPerformanceLogger;
var
Logger: TPerformanceLogger;
StartTime: TDateTime;
Elapsed: Integer;
begin
StartTime := Now;
Logger := TPerformanceLogger.Create('Test operation');
try
// 模拟操作
Sleep(100);
finally
Logger.Free;
end;
Elapsed := MilliSecondsBetween(Now, StartTime);
Check(Elapsed >= 100, 'Performance logger should record time');
end;
procedure TTestLogManager.TestLogExport;
var
JSONArray: TJSONArray;
begin
LogManager.Info('Test log for export');
JSONArray := LogManager.ExportToJSON;
try
CheckNotNull(JSONArray);
Check(JSONArray.Count > 0, 'Log export should return data');
finally
JSONArray.Free;
end;
end;
procedure TTestLogManager.TestUIMonitoring;
begin
LogManager.LogUIOperation('Click', 'Button1', 50);
LogManager.LogUIOperation('Select', 'ComboBox1', -1);
Check(True, 'UI monitoring should not throw exception');
end;
procedure TTestLogManager.TestNetworkMonitoring;
begin
LogManager.LogNetworkRequest('http://example.com/api', 'GET', 200, 150);
LogManager.LogNetworkRequest('http://example.com/api', 'POST', 201, 200);
LogManager.LogNetworkRequest('http://example.com/api', 'GET', 404, 100);
LogManager.LogNetworkRequest('http://example.com/api', 'POST', 500, 300);
Check(True, 'Network monitoring should not throw exception');
end;
procedure TTestLogManager.TestFormMonitoring;
begin
LogManager.LogFormShow('MainForm', 100);
LogManager.LogFormShow('LoginForm', -1);
LogManager.LogFormClose('MainForm', 50);
LogManager.LogFormClose('LoginForm', -1);
Check(True, 'Form monitoring should not throw exception');
end;
procedure TTestLogManager.TestDataOperationMonitoring;
begin
LogManager.LogDataOperation('INSERT', 10, 25);
LogManager.LogDataOperation('UPDATE', 5, -1);
LogManager.LogDataOperation('DELETE', 3, 15);
Check(True, 'Data operation monitoring should not throw exception');
end;
procedure TTestLogManager.TestLogCategoriesFilter;
var
Logs: TArray<TLogEntry>;
begin
LogManager.ClearLogs;
LogManager.InfoCategory(lcBusiness, 'Business log 1');
LogManager.InfoCategory(lcDevice, 'Device log 1');
LogManager.InfoCategory(lcNetwork, 'Network log 1');
Logs := LogManager.GetLogs(llInfo, [lcBusiness, lcDevice]);
Check(Length(Logs) >= 0, 'Should return filtered logs');
end;
{ TTestConfigManager }
procedure TTestConfigManager.TestConfigLoading;
var
Config: TConfigManager;
Value: string;
begin
Config := TConfigManager.Create('test_config.ini');
try
Value := Config.GetString('Test', 'Key', 'Default');
CheckEquals('Default', Value);
finally
Config.Free;
end;
end;
procedure TTestConfigManager.TestConfigSaving;
var
Config: TConfigManager;
Value: string;
begin
Config := TConfigManager.Create('test_config.ini');
try
Config.SetString('Test', 'Key', 'Value');
Config.Save;
// 重新加载验证
Config.Load;
Value := Config.GetString('Test', 'Key', 'Default');
CheckEquals('Value', Value);
finally
Config.Free;
end;
end;
procedure TTestConfigManager.TestConfigTypes;
var
Config: TConfigManager;
StrValue: string;
IntValue: Integer;
BoolValue: Boolean;
FloatValue: Double;
begin
Config := TConfigManager.Create('test_config.ini');
try
Config.SetString('Test', 'String', 'Hello');
Config.SetInteger('Test', 'Integer', 123);
Config.SetBoolean('Test', 'Boolean', True);
Config.SetFloat('Test', 'Float', 123.45);
StrValue := Config.GetString('Test', 'String', 'Default');
IntValue := Config.GetInteger('Test', 'Integer', 0);
BoolValue := Config.GetBoolean('Test', 'Boolean', False);
FloatValue := Config.GetFloat('Test', 'Float', 0.0);
CheckEquals('Hello', StrValue);
CheckEquals(123, IntValue);
CheckEquals(True, BoolValue);
CheckEquals(123.45, FloatValue, 0.01);
finally
Config.Free;
end;
end;
procedure TTestConfigManager.TestAppConfig;
begin
CheckNotNull(Config, 'App config should be created');
CheckNotNull(Config.GetServerURL, 'Server URL should be set');
Check(Config.GetServerPort > 0, 'Server port should be valid');
Check(Config.GetTimeout > 0, 'Timeout should be valid');
end;
procedure TTestConfigManager.TestAppConfigExtended;
begin
CheckNotNull(Config.GetFileServerPath, 'File server path should be set');
CheckNotNull(Config.GetBackupServerPath, 'Backup server path should be set');
Check(Config.GetSyncInterval > 0, 'Sync interval should be valid');
Check(Config.GetMaxRetryCount > 0, 'Max retry count should be valid');
Check(Config.GetLogFileMaxSize > 0, 'Log file max size should be valid');
end;
procedure TTestConfigManager.TestConfigArrayAndObject;
var
Config: TConfigManager;
ArrayValue: TArray<string>;
begin
Config := TConfigManager.Create('test_config.ini');
try
SetLength(ArrayValue, 3);
ArrayValue[0] := 'item1';
ArrayValue[1] := 'item2';
ArrayValue[2] := 'item3';
Config.SetArray('Test', 'Array', ArrayValue);
ArrayValue := Config.GetArray('Test', 'Array', []);
Check(Length(ArrayValue) = 3, 'Array should have 3 items');
CheckEquals('item1', ArrayValue[0]);
CheckEquals('item2', ArrayValue[1]);
CheckEquals('item3', ArrayValue[2]);
finally
Config.Free;
end;
end;
{ TTestBusinessServices }
procedure TTestBusinessServices.TestAuthService;
var
AuthService: TAuthService;
Result: TAuthResult;
begin
AuthService := TAuthService.Create;
try
Result := AuthService.Login('test', 'test');
Check(Result.Success, 'Login should succeed');
CheckNotNull(Result.Token, 'Token should be returned');
finally
AuthService.Free;
end;
end;
procedure TTestBusinessServices.TestWorkOrderService;
var
WorkOrderService: TWorkOrderService;
Orders: TArray<TWorkOrderInfo>;
begin
WorkOrderService := TWorkOrderService.Create('test-token');
try
Orders := WorkOrderService.GetWorkOrderList;
Check(Length(Orders) >= 0, 'Work order list should be returned');
finally
WorkOrderService.Free;
end;
end;
procedure TTestBusinessServices.TestDeviceService;
var
DeviceService: TDeviceService;
Status: TDeviceStatus;
Devices: TArray<TDeviceStatus>;
begin
DeviceService := TDeviceService.Create;
try
Status := DeviceService.GetDeviceStatus('PLC-001');
Check(Status.DeviceID = 'PLC-001', 'Device status should be returned');
Devices := DeviceService.GetAllDevices;
Check(Length(Devices) >= 0, 'Device list should be returned');
finally
DeviceService.Free;
end;
end;
procedure TTestBusinessServices.TestSyncService;
var
SyncService: TSyncService;
Data: TJSONObject;
Result: Boolean;
begin
SyncService := TSyncService.Create('test-token');
try
Data := TJSONObject.Create;
try
Data.AddPair('test', 'value');
Result := SyncService.SyncData(Data);
Check(Result, 'Sync should succeed');
finally
Data.Free;
end;
finally
SyncService.Free;
end;
end;
procedure TTestBusinessServices.TestAuthServiceLogout;
var
AuthService: TAuthService;
Result: Boolean;
begin
AuthService := TAuthService.Create;
try
Result := AuthService.Logout('test-token');
Check(Result, 'Logout should succeed');
finally
AuthService.Free;
end;
end;
procedure TTestBusinessServices.TestAuthServiceRefreshToken;
var
AuthService: TAuthService;
NewToken: string;
begin
AuthService := TAuthService.Create;
try
NewToken := AuthService.RefreshToken('old-token');
CheckNotNull(NewToken, 'Refreshed token should be returned');
CheckNotSame('old-token', NewToken, 'Token should be different');
finally
AuthService.Free;
end;
end;
procedure TTestBusinessServices.TestWorkOrderServiceCreate;
var
WorkOrderService: TWorkOrderService;
OrderInfo: TWorkOrderInfo;
NewOrderID: string;
begin
WorkOrderService := TWorkOrderService.Create('test-token');
try
OrderInfo.Clear;
OrderInfo.OrderNumber := 'WO-NEW-001';
OrderInfo.MaterialID := 'MAT-001';
OrderInfo.MaterialName := 'Test Material';
OrderInfo.Quantity := 100;
NewOrderID := WorkOrderService.CreateWorkOrder(OrderInfo);
CheckNotNull(NewOrderID, 'New order ID should be returned');
finally
WorkOrderService.Free;
end;
end;
procedure TTestBusinessServices.TestWorkOrderServiceUpdateStatus;
var
WorkOrderService: TWorkOrderService;
Result: Boolean;
begin
WorkOrderService := TWorkOrderService.Create('test-token');
try
Result := WorkOrderService.UpdateWorkOrderStatus('WO-001', 'Completed');
Check(Result, 'Update status should succeed');
finally
WorkOrderService.Free;
end;
end;
procedure TTestBusinessServices.TestWorkOrderServiceReportProduction;
var
WorkOrderService: TWorkOrderService;
Result: Boolean;
begin
WorkOrderService := TWorkOrderService.Create('test-token');
try
Result := WorkOrderService.ReportProduction('WO-001', 'Process-001', '50');
Check(Result, 'Report production should succeed');
finally
WorkOrderService.Free;
end;
end;
procedure TTestBusinessServices.TestDeviceServiceConnectDisconnect;
var
DeviceService: TDeviceService;
Result: Boolean;
begin
DeviceService := TDeviceService.Create;
try
Result := DeviceService.ConnectDevice('PLC-001');
Check(Result, 'Connect device should succeed');
Result := DeviceService.DisconnectDevice('PLC-001');
Check(Result, 'Disconnect device should succeed');
finally
DeviceService.Free;
end;
end;
procedure TTestBusinessServices.TestDeviceServiceSendCommand;
var
DeviceService: TDeviceService;
Response: string;
begin
DeviceService := TDeviceService.Create;
try
Response := DeviceService.SendCommand('PLC-001', 'READ_D100');
CheckNotNull(Response, 'Command response should be returned');
Check(Response <> '', 'Command response should not be empty');
finally
DeviceService.Free;
end;
end;
procedure TTestBusinessServices.TestSyncServiceBatch;
var
SyncService: TSyncService;
DataArray: TJSONArray;
Result: Boolean;
begin
SyncService := TSyncService.Create('test-token');
try
DataArray := TJSONArray.Create;
try
DataArray.AddElement(TJSONObject.Create.AddPair('key', 'value1'));
DataArray.AddElement(TJSONObject.Create.AddPair('key', 'value2'));
Result := SyncService.SyncBatchData(DataArray);
Check(Result, 'Batch sync should succeed');
finally
DataArray.Free;
end;
finally
SyncService.Free;
end;
end;
procedure TTestBusinessServices.TestSyncServiceRetry;
var
SyncService: TSyncService;
RetryCount: Integer;
begin
SyncService := TSyncService.Create('test-token');
try
RetryCount := SyncService.RetryFailedSyncs;
Check(RetryCount >= 0, 'Retry count should be non-negative');
finally
SyncService.Free;
end;
end;
procedure TTestBusinessServices.TestProductionReportingService;
var
ProductionService: TProductionReportingService;
Result: Boolean;
begin
ProductionService := TProductionReportingService.Create('test-token');
try
Result := ProductionService.ReportProduction('WO-001', 'Process-001', '50', 'LOT-001');
Check(Result, 'Report production should succeed');
finally
ProductionService.Free;
end;
end;
procedure TTestBusinessServices.TestProductionReportingServiceValidateUser;
var
ProductionService: TProductionReportingService;
Result: Boolean;
begin
ProductionService := TProductionReportingService.Create('test-token');
try
Result := ProductionService.ValidateUser('test-user');
Check(Result, 'Validate user should succeed');
finally
ProductionService.Free;
end;
end;
procedure TTestBusinessServices.TestProductionReportingServiceGetWorkOrderInfo;
var
ProductionService: TProductionReportingService;
WorkOrderInfo: TJSONObject;
begin
ProductionService := TProductionReportingService.Create('test-token');
try
WorkOrderInfo := ProductionService.GetWorkOrderInfo('LOT-001');
CheckNotNull(WorkOrderInfo, 'Work order info should be returned');
CheckNotNull(WorkOrderInfo.GetValue('lotNo'), 'Lot number should be present');
finally
ProductionService.Free;
end;
end;
procedure TTestBusinessServices.TestProductionReportingServiceGetProcessList;
var
ProductionService: TProductionReportingService;
ProcessList: TJSONArray;
begin
ProductionService := TProductionReportingService.Create('test-token');
try
ProcessList := ProductionService.GetProcessList('LOT-001');
CheckNotNull(ProcessList, 'Process list should be returned');
Check(ProcessList.Count >= 0, 'Process list should have at least 0 items');
finally
ProductionService.Free;
end;
end;
procedure TTestBusinessServices.TestProductionReportingServiceValidateGoodsNo;
var
ProductionService: TProductionReportingService;
Result: Boolean;
begin
ProductionService := TProductionReportingService.Create('test-token');
try
Result := ProductionService.ValidateGoodsNo('ITEM-001', 'PROCESS-001', 'WO-001');
Check(Result, 'Validate goods no should succeed');
finally
ProductionService.Free;
end;
end;
procedure TTestBusinessServices.TestProductionReportingServiceSubmitData;
var
ProductionService: TProductionReportingService;
Result: Boolean;
begin
ProductionService := TProductionReportingService.Create('test-token');
try
Result := ProductionService.SubmitProductionData('test-user', 'LOT-001', '1', 'ITEM-001');
Check(Result, 'Submit production data should succeed');
finally
ProductionService.Free;
end;
end;
procedure TTestBusinessServices.TestDeviceConfigService;
var
DeviceConfigService: TDeviceConfigService;
Result: Boolean;
begin
DeviceConfigService := TDeviceConfigService.Create;
try
Result := DeviceConfigService.LoadDeviceConfig;
Check(Result, 'Load device config should succeed');
Result := DeviceConfigService.SaveDeviceConfig;
Check(Result, 'Save device config should succeed');
finally
DeviceConfigService.Free;
end;
end;
procedure TTestBusinessServices.TestDataAccessService;
var
DataAccessService: TDataAccessService;
Value: string;
begin
DataAccessService := TDataAccessService.Create;
try
Value := DataAccessService.ReadConfigValue('Test', 'Key', 'Default');
CheckEquals('Default', Value, 'Default value should be returned');
DataAccessService.WriteConfigValue('Test', 'Key', 'Value');
Value := DataAccessService.ReadConfigValue('Test', 'Key', 'Default');
CheckEquals('Value', Value, 'Written value should be returned');
finally
DataAccessService.Free;
end;
end;
{ TTestCommonUtils }
procedure TTestCommonUtils.TestValidator;
begin
Check(TValidator.IsEmpty(''), 'Empty string should be detected');
Check(not TValidator.IsEmpty('Test'), 'Non-empty string should not be detected as empty');
Check(TValidator.IsInteger('123'), 'Valid integer should be detected');
Check(not TValidator.IsInteger('abc'), 'Invalid integer should not be detected');
Check(TValidator.IsFloat('123.45'), 'Valid float should be detected');
Check(not TValidator.IsFloat('abc'), 'Invalid float should not be detected');
end;
procedure TTestCommonUtils.TestStringHelper;
var
S: string;
begin
S := '123';
Check(S.IsInteger, 'String should be detected as integer');
S := '123.45';
Check(S.IsFloat, 'String should be detected as float');
S := 'Hello';
Check(S.Contains('ell'), 'String should contain substring');
Check(S.StartsWith('He'), 'String should start with prefix');
Check(S.EndsWith('lo'), 'String should end with suffix');
end;
procedure TTestCommonUtils.TestDateTimeHelper;
var
DT: TDateTime;
begin
DT := Now;
Check(TDateTimeHelper.IsToday(DT), 'Date should be today');
Check(TDateTimeHelper.IsSameDay(DT, DT), 'Date should be same day');
end;
procedure TTestCommonUtils.TestFileHelper;
var
TempFile: string;
Content: string;
begin
TempFile := TFileHelper.GetTempFileName('.txt');
try
TFileHelper.WriteTextFile(TempFile, 'Test content');
Content := TFileHelper.ReadTextFile(TempFile);
CheckEquals('Test content', Content, 'File content should match');
finally
if FileExists(TempFile) then
DeleteFile(TempFile);
end;
end;
procedure TTestCommonUtils.TestJSONHelper;
var
JSON: TJSONObject;
Value: string;
IntValue: Integer;
begin
JSON := TJSONObject.Create;
try
JSON.AddPair('string', 'value');
JSON.AddPair('integer', TJSONNumber.Create(123));
Value := TJSONHelper.GetString(JSON, 'string', 'default');
CheckEquals('value', Value, 'String value should be retrieved');
IntValue := TJSONHelper.GetInteger(JSON, 'integer', 0);
CheckEquals(123, IntValue, 'Integer value should be retrieved');
finally
JSON.Free;
end;
end;
initialization
RegisterTest('ExceptionHandler', TTestExceptionHandler.Suite);
RegisterTest('LogManager', TTestLogManager.Suite);
RegisterTest('ConfigManager', TTestConfigManager.Suite);
RegisterTest('BusinessServices', TTestBusinessServices.Suite);
RegisterTest('CommonUtils', TTestCommonUtils.Suite);
end.