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