Jump to content

coxidat

Members
  • Content Count

    1
  • Joined

  • Last visited

Posts posted by coxidat


  1. 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
×