Mocking and returned values

130 views
Skip to first unread message

Pio Pio

unread,
Dec 28, 2021, 11:37:02 AM12/28/21
to Spring4D
Hello,

I am trying to test part of my code but I cannot get my head around the mocking.

The following is a short version of the code just to reproduce the problem:

{$M+}
unit TestTrash;

interface

uses
TestFramework,
System.Classes,
System.SysUtils,
System.Generics.Collections,
DSharp.Testing.Mock,
Spring.Mocking;

type
Mode = (Live, Simulation);

TSide = (Unknown, sideFront, SideBack);

TStatus = (stUnknown, stComplete, stPartial);

Order = record
Side: TSide;
SelectionId: string;
end;

TOrderBy = (obNone, odAscending, obDescending);

TOrderProjection = (opNone, opALL, opIncomplete, opComplete);

TSort = (sNone, sTopToBottom, sBottomToTop);

TTimeRangeObj = class(TObject)
private
fFrom: TDateTime;
fTo: TDateTime;
public
end;

TOrderSummaryObj = class(TObject)
private
fSelectionId: Int64;
fSide: TSide;
fStatus: TStatus;
public
property iSelectionId: int64 read fSelectionId write fSelectionId;
property eSide: TSide read fSide write fSide;
property eStatus: TStatus read fStatus write fStatus;
end;

ArrayOfTOrderSummaryObj = array of TOrderSummaryObj;

TOrderSummaryReportObj = class(TObject)
public
var
aOrders: ArrayOfTOrderSummaryObj;
end;

ICheckCurrentOrderBL = interface
['{1314259C-E390-45AE-B97E-504BF49EA8F4}']
function CheckAllCurrentOrders(sSessionToken, sAppKey: string; Id: integer; slIds: TStringList;
slMIds: TStringList; eOProjection: TOrderProjection; oDateRange: TTimeRangeObj; eOrderBy:
TOrderBy; eSortDir: TSort; var oResult: TOrderSummaryReportObj): boolean;
end;

IEqualizeBL = interface
['{100978BB-B759-47F2-B4E5-76573BB6CA90}']
function ScanAllCurrentTrades(const aMID, aToken, aAppKey: string): Boolean;
end;

TEqualizeBL = class(TInterfacedObject, IEqualizeBL)
private
FCheckCurrent: ICheckCurrentOrderBL;
FCheckCurrentLive: ICheckCurrentOrderBL;
FCheckCurrentSimulation: ICheckCurrentOrderBL;
public
constructor Create(const aCheckCurrentLive, aCheckCurrentOrdersSimulation: ICheckCurrentOrderBL);
reintroduce;
function ScanAllCurrentTrades(const aMID, aToken, aAppKey: string): Boolean;
end;

TestTEqualizeBL = class(TTestCase)
strict private
FEqualizeBL: TEqualizeBL;
FMockCheckOrdersLive: Spring.Mocking.Mock<ICheckCurrentOrderBL>;
FMockCheckOrdersSimulation: Spring.Mocking.Mock<ICheckCurrentOrderBL>;
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestScanAllCurrent2;
end;

implementation

uses
LBS_BetfairAPINGClasses;

procedure TestTEqualizeBL.SetUp;
begin
FMockCheckOrdersLive := FMockCheckOrdersLive.Create;
FMockCheckOrdersSimulation := FMockCheckOrdersSimulation.Create;
FEqualizeBL := TEqualizeBL.Create(FMockCheckOrdersLive, FMockCheckOrdersSimulation);
end;

procedure TestTEqualizeBL.TearDown;
begin
FEqualizeBL.Free;
FEqualizeBL := nil;
end;

procedure TestTEqualizeBL.TestScanAllCurrent2;
var
ReturnValue: Boolean;
AppKey: string;
aToken: string;
aMID: string;
aResult: TOrderSummaryReportObj;
I: Integer;
begin
aResult := nil;
aResult := TOrderSummaryReportObj.Create;
// E2003 Undeclared identifier: 'aResult' in the IDE watch list but the application progresses regularly
SetLength(aResult.aOrders, 10);
for I := 0 to Length(aResult.aOrders) - 1 do
begin
aResult.aOrders[I] := TOrderSummaryObj.Create;
end;
aResult.aOrders[2].eStatus := stComplete;


{ the aim here is
1) make sure that FCheckCurrent.CheckAllCurrentOrders returns True
2) FCheckCurrent.CheckAllCurrentOrders must return oResult with all the data from aResult
}
FMockCheckOrdersSimulation.Setup.Returns(True).When.CheckAllCurrentOrders(Arg.IsAny<string>, Arg.IsAny
<string>, Arg.IsAny<integer>, Arg.IsAny<tstringlist>, Arg.IsAny<tstringlist>, Arg.IsAny<
TOrderProjection>, Arg.IsAny<TTimeRangeObj>, Arg.IsAny<TOrderBy>, Arg.IsAny<TSort>,
TOrderSummaryReportObj(aResult));

FMockCheckOrdersSimulation.Setup.Executes(
function(const call: TCallInfo): TValue
begin
call[9] := aResult;
end).When.CheckAllCurrentOrders(Arg.IsAny<string>, Arg.IsAny<string>, Arg.IsAny<integer>, Arg.IsAny
<tstringlist>, Arg.IsAny<tstringlist>, Arg.IsAny<TOrderProjection>, Arg.IsAny<TTimeRangeObj>,
Arg.IsAny<TOrderBy>, Arg.IsAny<TSort>, TOrderSummaryReportObj(aResult));


ReturnValue := FEqualizeBL.ScanAllCurrentTrades(aMID, aToken, AppKey);
CheckFalse(ReturnValue);
aResult.Free;
end;

constructor TEqualizeBL.Create(const aCheckCurrentLive, aCheckCurrentOrdersSimulation:
ICheckCurrentOrderBL);
begin
inherited Create;
FCheckCurrent := aCheckCurrentOrdersSimulation;
FCheckCurrentLive := aCheckCurrentLive;
FCheckCurrentSimulation := aCheckCurrentOrdersSimulation;
end;

function TEqualizeBL.ScanAllCurrentTrades(const aMID, aToken, aAppKey: string): Boolean;
var
I: longint;
iEx: integer;
slIds: TStringList;
slMIds: TStringList;
eProjection: TOrderProjection;
oPlacedDateRange: TTimeRangeObj;
eOrderBy: TOrderBy;
eSort: TSort;
oResult: TOrderSummaryReportObj;
begin
try
try
oResult := nil;
iEx := 1;
slIds := TStringList.create;
slMIds := TStringList.create;
slMIds.add(aMID);
eProjection := opALL;
oPlacedDateRange := nil;
eOrderBy := odAscending;
eSort := sTopToBottom;

Result := FCheckCurrent.CheckAllCurrentOrders(aToken, aAppKey, iEx, slIds, slMIds, eProjection,
oPlacedDateRange, eOrderBy, eSort, oResult);
if Result = True then
begin
if oResult <> nil then
begin
if length(oResult.aOrders) > 0 then
begin
I := 0;
while (I <= length(oResult.aOrders) - 1) do
begin
end;
end;
FreeAndNil(oResult);
end;
end;
except
end;
finally
slIds.free;
slMIds.free;
oPlacedDateRange.free;
end;
end;

initialization
RegisterTest(TestTEqualizeBL.Suite);

end.



The first issue is when I run TestScanAllCurrent2, I have an E2003 Undeclared identifier: 'aResult' in the IDE watch list. The application progresses regularly but I don't know why the value of aResult doesn't show up in the IDE.
If I remove the following code:

  FMockCheckOrdersSimulation.Setup.Executes(
    function(const call: TCallInfo): TValue
    begin
      call[9] := aResult;
    end).When.CheckAllCurrentOrders(Arg.IsAny<string>, Arg.IsAny<string>, Arg.IsAny<integer>, Arg.IsAny
      <tstringlist>, Arg.IsAny<tstringlist>, Arg.IsAny<TOrderProjection>, Arg.IsAny<TTimeRangeObj>,
      Arg.IsAny<TOrderBy>, Arg.IsAny<TSort>, TOrderSummaryReportObj(aResult));
then the values of aResult in the IDE watch List are back. Do you know why?


The second issue I have I have to to make sure FCheckCurrent.CheckAllCurrentOrders returns True AND also returns oResult with all the data I have added previously in aResult.
The best I came up with is the code

  FMockCheckOrdersSimulation.Setup.Returns(True).When.CheckAllCurrentOrders(Arg.IsAny<string>, Arg.IsAny
    <string>, Arg.IsAny<integer>, Arg.IsAny<tstringlist>, Arg.IsAny<tstringlist>, Arg.IsAny<
    TOrderProjection>, Arg.IsAny<TTimeRangeObj>, Arg.IsAny<TOrderBy>, Arg.IsAny<TSort>,
    TOrderSummaryReportObj(aResult));

  FMockCheckOrdersSimulation.Setup.Executes(
    function(const call: TCallInfo): TValue
    begin
      call[9] := aResult;
    end).When.CheckAllCurrentOrders(Arg.IsAny<string>, Arg.IsAny<string>, Arg.IsAny<integer>, Arg.IsAny
      <tstringlist>, Arg.IsAny<tstringlist>, Arg.IsAny<TOrderProjection>, Arg.IsAny<TTimeRangeObj>,
      Arg.IsAny<TOrderBy>, Arg.IsAny<TSort>, TOrderSummaryReportObj(aResult));


above but that I cannot have both. It seems the second part of the code overrides the first one.

What am I doing wrong?

Apologizes for the lacking of code formatting but I cannot find the feature in Google Groups any longer.

Many thanks
Alberto

Pio Pio

unread,
Dec 29, 2021, 6:28:14 AM12/29/21
to Spring4D

Hello,

I have found the solution in this post https://groups.google.com/g/spring4d/c/l90aseC_wTM which appeared to be before mine.
The following code
FMockCheckOrdersSimulation.Setup.Returns(True).When.CheckAllCurrentOrders(Arg.IsAny, Arg.IsAny
, Arg.IsAny, Arg.IsAny, Arg.IsAny, Arg.IsAny<
TOrderProjection>, Arg.IsAny, Arg.IsAny, Arg.IsAny,
TOrderSummaryReportObj(aResult));

FMockCheckOrdersSimulation.Setup.Executes(
function(const call: TCallInfo): TValue
begin
call[9] := aResult;

end).When.CheckAllCurrentOrders(Arg.IsAny, Arg.IsAny, Arg.IsAny, Arg.IsAny
, Arg.IsAny, Arg.IsAny, Arg.IsAny,
Arg.IsAny, Arg.IsAny, TOrderSummaryReportObj(aResult));


has been replaced with

FMockCheckOrdersSimulation .Setup.Executes(


function(const call: TCallInfo): TValue
begin

call[9] := oResult;
end).When.CheckAllCurrentOrders(Arg.IsAny, Arg.IsAny, Arg.IsAny, Arg.IsAny
, Arg.IsAny, Arg.IsAny< TOrderProjection>, Arg.IsAny<
TTimeRangeObj>, Arg.IsAny, Arg.IsAny, oResult);

Alberto

Reply all
Reply to author
Forward
0 new messages