Delphi   发布时间:2022-04-10  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Delphi单元测试为一个TThread与FreeOnTerminate = True大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
当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.

解决方法

将线程子类化以使其更可测. TThread和TObject提供了足够的钩子,您可以添加感应变量来观察它到达您想要的状态的某些点.

我看到你可能希望测试的这个特定类的三个方面:

>它根据发送给构造函数的值计算其Id属性的值.
>它计算新线程中的新Id属性,而不是调用构造函数的线程.
>完成后自动释放.

所有这些东西都可以从一个子类测试,但是很难测试,而不需要更改线程的接口. (所有其他答案到目前为止需要更改线程的界面,例如通过添加更多的构造函数参数或通过更改自身的开始方式,这可以使线程在实际程序中使用更加困难或至少更麻烦)

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;

大佬总结

以上是大佬教程为你收集整理的Delphi单元测试为一个TThread与FreeOnTerminate = True全部内容,希望文章能够帮你解决Delphi单元测试为一个TThread与FreeOnTerminate = True所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。