Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Delphi-Mocks | Fehler bei Verwendung von TValue (https://www.delphipraxis.net/190687-delphi-mocks-%7C-fehler-bei-verwendung-von-tvalue.html)

TimWu 27. Okt 2016 11:21

Delphi-Mocks | Fehler bei Verwendung von TValue
 
benutzt:
-DunitX
-delphi.mocks https://github.com/VSoftTechnologies/Delphi-Mocks

Hallo Leute,

ich habe folgendes Problem:

Ich habe einen Prozessor programiert und für diesen möchte ich eine Testklasse schreiben. Ich übergebe dem Prozessor ein Objekt, Einstellungen und einen Writer(dieser ist vom Interface IWriter).

Um den Prozessor zu testen erzeuge ich einen Mock vom IWriter, und dieser soll ermitteln ob der Prozessor, bedingt durch die Einstellungen, den richtigen Wert vom Typ TValue schreibt. Leider erzeugt dies eine Zugriffsverletzung:
Delphi-Quellcode:
procedure TTestRWProcessor.TestFieldsPrivate;
var
   TempWriter: TMock<IWriter>;
   lField: TRttiField;
begin
   TempWriter := TMock<IWriter>.Create;
   lField := FType.GetField('FPrivate');   //FType wird beim Setup erzeugt
   TempWriter.Setup.Expect.Once.When.add(lField ,TValue.FromVariant('private'));

   FProcessor.write(FObject, [soFieldsAll], TempWriter);

   TempWriter.VerifyAll;
end;
Um den Fehler zu ermitteln und ein bisschen zu probieren habe ich mir eine Klasse mit einem Objekt und einem Interface(ITest) gebaut. In dieser sind 3 Prozeduren, die eine benötigt einen String und die andere einen Value. Die dritte führt Beide aus.
Delphi-Quellcode:
procedure TTestObjekt.uebergebeWerteAnMock(aTest: ITest);
var
   lValue: TValue;
begin
   lValue := TValue.FromVariant('String');
   aTest.test2('bla');
   aTest.test3(lValue);
end;
Meine Testklasse
Delphi-Quellcode:
procedure TTestRechner.TestParams;
var
   tempLogger : TMock<ITest>;
   lValue : TValue;
begin
   lValue := TValue.FromVariant('String');
   tempLogger := TMock<ITest>.Create;
   tempLogger.Setup.Expect.Once.When.test2('bla');
//  tempLogger.Setup.Expect.Once.When.test3(lValue);
   FTestObjekt.uebergebeWerteAnMock(tempLogger);
   tempLogger.VerifyAll;
end;
Wenn Test3 ausgeklammert ist, klappt es, andernfals gibt es eine Zugriffsverletung.

Kennt jemand eine Lösung für das Problem?

Rollo62 27. Okt 2016 12:05

AW: Delphi-Mocks | Fehler bei Verwendung von TValue
 
Soweit ich weiss kann ein TValue den einmal festgelegten Typ nicht ändern.
es ist also KEIN Variant.

Vielleicht ist dass das Problem hier ?

Rollo

TimWu 27. Okt 2016 12:07

AW: Delphi-Mocks | Fehler bei Verwendung von TValue
 
Wenn ich den Wert so zuweise, bekomme ich ebenfalls eine Zugriffsverletzung.

Stevie 28. Okt 2016 09:10

AW: Delphi-Mocks | Fehler bei Verwendung von TValue
 
Poste doch einfach mal nen komplettes minimales Programm, was den Fehler nachstellt anstatt unvollständige Schnipsel, wo man nicht mehr machen kann, außer die :glaskugel: zu befragen.

TimWu 28. Okt 2016 10:04

AW: Delphi-Mocks | Fehler bei Verwendung von TValue
 
Die Test Unit

Delphi-Quellcode:
unit unitTest;

interface
uses
  DUnitX.TestFramework,
  Delphi.Mocks,
  System.Rtti,
  uTest;

type

  [TestFixture]
  TTestRechner = class(TObject)
  private
     FTestObjekt: TTestObjekt;
  public
    [Setup]
    procedure Setup; //TestObjekt erzeugen
    [TearDown]
    procedure TearDown; //Testobjekt freigeben
    [Test]
    procedure Test;
  end;

implementation
//***

procedure TTestRechner.Test;
var
   tempLogger : TMock<ITest>;
        lValue : TValue;
        lVariant: Variant;
begin
    lValue := 0;
    tempLogger := TMock<ITest>.Create;
    tempLogger.Setup.Expect.Once.When.test2('bla');
    tempLogger.Setup.Expect.Once.When.test3(lValue);
    FTestObjekt.uebergebeWerteAnMock(tempLogger);
    tempLogger.VerifyAll;
end;

initialization
  TDUnitX.RegisterTestFixture(TTestRechner);
end.
Die zu testende Unit

Delphi-Quellcode:
unit uTest;

interface
uses System.rtti;

type
   {$M+}
   ITest = interface
    procedure test2(aName: String);
    procedure test3(aValue: TValue);
  end;


   TTestObjekt = class(TObject)
  public
    procedure uebergebeWerteAnMock(aTest: ITest);
  end;

implementation

procedure TTestObjekt.uebergebeWerteAnMock(aTest: ITest);
var
   lValue: TValue;
begin
   lValue := 0;
   aTest.test2('bla');
   aTest.test3(lValue);
end;

end.

Es knallt mit ner Zugriffsverletzung, wenn die Funktion des Interfaces test3 mit TValue aufgerufen wird.

Stevie 28. Okt 2016 12:16

AW: Delphi-Mocks | Fehler bei Verwendung von TValue
 
Die Argument Matcher arbeiten nicht richtig mit Record typen zusammen (siehe Issue 39).
Ich habe seinerzeit Vincent meinen damaligen Code zur Verfügung gestellt, der aber keinen Anspruch an Vollständigkeit hatte (Records vergleichen z.b. funktioniert nicht wirklich).
Dass das relativ komplex werden kann, sieht man an der entsprechenden Routine in Spring4D.

P.S. Du kannst in der Unit Delphi.Mocks.Expectations.pas im implementation uses Delphi.Mocks.Helpers durch Spring (aus dem release/1.2 branch) ersetzen, dann sollte das funktionieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz