Currently I am trying to use "TTestDataProvider" to provide my test cases with test data.
However, in the following example, I have encountered a memory release problem that I cannot solve myself.
The destructor of the "TObjectProvider" class seems to be called before the actual test run:
unit UTest;
interface
uses
DUnitX.TestFramework, DUnitX.InternalDataProvider, DUnitX.Types,
Generics.Collections;
type
TTestObj = class
Name: string;
end;
TObjectProvider = class(TTestDataProvider)
private
type
TTestData = record
Name: string;
Data: TTestObj;
end;
var
FList: TList<TTestData>;
public
constructor Create; override;
destructor Destroy; override;
function GetCaseCount(const AMethodName: string): Integer; override;
function GetCaseName(const AMethodName: string; const ACaseNumber: Integer): string; override;
function GetCaseParams(const AMethodName: string; const ACaseNumber: Integer): TValueArray; override;
end;
type
[TestFixture]
TMyTestObject = class
public
[TestCaseProvider('TObjectProvider')]
procedure TestObject(const AValue: TTestObj);
end;
implementation
uses
SysUtils, Math, DUnitX.TestDataProvider;
{ =========================================================================== }
constructor TObjectProvider.Create;
var
Item: TTestData;
begin
inherited;
FList := TList<TTestData>.Create;
Item.Name := 'Testobject 1';
Item.Data := TTestObj.Create;
Item.Data.Name := 'Testobject.Name 1';
FList.Add(Item);
Item.Name := 'Testobject 2';
Item.Data := TTestObj.Create;
Item.Data.Name := 'Testobject.Name 2';
FList.Add(Item);
end;
{ =========================================================================== }
destructor TObjectProvider.Destroy;
var
item: TTestData;
begin
for item in FList do //<-- Remove me to succeed but leak the objects
FreeAndNil(item.Data); //<-- Remove me too.
FreeAndNil(FList);
inherited;
end;
{ =========================================================================== }
function TObjectProvider.GetCaseCount(const AMethodName: string): Integer;
begin
Result := FList.Count;
end;
{ =========================================================================== }
function TObjectProvider.GetCaseName(const AMethodName: string; const ACaseNumber: Integer): string;
begin
Result := Self.ClassName + '[' + FList[ACaseNumber].Name + ']';
end;
{ =========================================================================== }
function TObjectProvider.GetCaseParams(const AMethodName: string; const ACaseNumber: Integer): TValueArray;
begin
SetLength(Result, 1);
Result[0] := FList[ACaseNumber].Data;
end;
{ =========================================================================== }
{ TMyTestObject }
procedure TMyTestObject.TestObject(const AValue: TTestObj);
begin
Assert.IsNotNull(AValue);
Assert.IsNotEmpty(AValue.Name);
end;
{ =========================================================================== }
initialization
TestDataProviderManager.RegisterProvider('TObjectProvider', TObjectProvider);
end.
Can anyone give me a tip on how to solve this problem?