Jump to content
coxidat

How do i correctly free the data of a TTestDataProvider?

Recommended Posts

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?

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×