gpt4 book ai didi

FreeOnTerminate = True 的 TThread 的 Delphi 单元测试

转载 作者:行者123 更新时间:2023-12-03 14:39:03 24 4
gpt4 key购买 nike

当 FreeOnTerminate = True 时,为 TThread 后代编写 Delphi DUnit 测试的最佳方法是什么? TThread 后代返回一个我需要测试的引用,但我不知道如何等待线程在测试中完成...

unit uThreadTests;

interface

uses
Classes, TestFramework;

type

TMyThread = class(TThread)
strict private
FId: Integer;
protected
procedure Execute; override;
public
constructor Create(AId: Integer);
property Id: Integer read FId;
end;

TestTMyThread = class(TTestCase)
strict private
FMyId: Integer;
procedure OnThreadTerminate(Sender: TObject);
protected
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestMyThread;
end;

implementation

{ TMyThread }

constructor TMyThread.Create(AId: Integer);
begin
FreeOnTerminate := True;
FId := AId;

inherited Create(False);
end;

procedure TMyThread.Execute;
begin
inherited;

FId := FId + 1;
end;

{ TestTMyThread }

procedure TestTMyThread.TestMyThread;
//var
// LThread: TMyThread;
begin
// LThread := TMyThread.Create(1);
// LThread.OnTerminate := OnThreadTerminate;
// LThread.WaitFor;
// CheckEquals(2, FMyId);
// LThread.Free;
///// The above commented out code is only useful of FreeOnTerminate = False;

with TMyThread.Create(1) do
begin
OnTerminate := OnThreadTerminate;
WaitFor; /// Not sure how else to wait for the thread to finish?
end;

CheckEquals(2, FMyId);
end;

procedure TestTMyThread.OnThreadTerminate(Sender: TObject);
begin
FMyId := (Sender as TMyThread).Id;
end; /// When FreeOnTerminate = True - THIS LINE CAUSES ERROR: Thread Error the handle is invalid

procedure TestTMyThread.SetUp;
begin
inherited;

end;

procedure TestTMyThread.TearDown;
begin
inherited;

end;

initialization
RegisterTests([TestTMyThread.Suite]);


end.

任何想法都会受到欢迎。

德尔福2010。

最佳答案

对线程进行子类化,使其更易于测试。 TThreadTObject 提供了足够的钩子(Hook),您可以添加传感变量来观察它是否达到了您希望它具有的状态的某些点。

我发现您可能希望测试这个特定类的三个方面:

  1. 它根据发送到构造函数的值计算其 Id 属性的值。
  2. 它在新线程中计算新的 Id 属性,而不是在调用构造函数的线程中。
  3. 完成后它会自行释放。

所有这些东西都可以从子类进行测试,但如果不更改线程的接口(interface),则很难进行测试。 (到目前为止,所有其他答案都需要更改线程的接口(interface),例如通过添加更多构造函数参数或更改其自身启动的方式。这可能会使线程在实际程序中使用起来更困难,或者至少更麻烦。)

type
PTestData = ^TTestData;
TTestData = record
Event: TEvent;
OriginalId: Integer;
FinalId: Integer;
end;

TTestableMyThread = class(TMyThread)
private
FData: PTestData;
public
constructor Create(AId: Integer; AData: PTestData);
destructor Destroy; override;
procedure AfterConstruction; override;
end;

constructor TTestableMyThread.Create(AId: Integer; const AData: PTestData);
begin
inherited Create(AId);
FData := AData;
end;

destructor TestableMyThread.Destroy;
begin
inherited;
FData.FinalId := Id;
// Tell the test that the thread has been freed
FData.Event.SetEvent;
end;

procedure TTestableMyThread.AfterConstruction;
begin
FData.OriginalId := Id;
inherited; // Call this last because this is where the thread starts running
end;

使用该子类,可以编写一个测试来检查前面确定的三个质量:

procedure TestTMyThread.TestMyThread;
var
Data: TTestData;
WaitResult: TWaitResult;
begin
Data.OriginalId := -1;
Data.FinalId := -1;
Data.Event := TSimpleEvent.Create;
try
TTestableMyThread.Create(1, @Data);

// We don't free the thread, and the event is only set in the destructor,
// so if the event is signaled, it means the thread freed itself: That
// aspect of the test implicitly passes. We don't want to wait forever,
// though, so we fail the test if we have to wait too long. Either the
// Execute method is taking too long to do its computations, or the thread
// isn't freeing itself.
// Adjust the timeout based on expected performance of Execute.
WaitResult := Data.Event.WaitFor(5000);
case WaitResult of
wrSignaled: ; // This is the expected result
wrTimeOut: Fail('Timed out waiting for thread');
wrAbandoned: Fail('Event was abandoned');
wrError: RaiseLastOSError(Data.Event.LastError);
else Fail('Unanticipated error waiting for thread');
end;

CheckNotEquals(2, Data.OriginalId,
'Didn''t wait till Execute to calculate Id');
CheckEquals(2, Data.FinalId,
'Calculated wrong Id value');
finally
Data.Event.Free;
end;
end;

关于FreeOnTerminate = True 的 TThread 的 Delphi 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15514295/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com