The class I am doing Unit Testing scrolls each record of a DB table and sum the value in a field to the previous value. The following is the class reduced to the bone:
procedure TSumList.Sum;
var
FSum:integer;
begin
FSum:=0;
FDB.First;
while not FDB.EOF do
begin
FSum:=FSum+FDB.GetAmount;
FDB.Next;
end;
end;
FDB refers to the DB mock interface named IIDBTable.
The following is the DB mock for the dependency injection:
IIDBTable = interface
['{A299D1D6-93AF-45CC-8DE2-9A4EE188C352}']
procedure First;
procedure Next;
function EOF : boolean;
function GetAmount:integer;
end;
TMockDBTable = class (TInterfacedObject,IDBTable)
procedure First;
procedure Next;
function EOF : boolean;
function GetAmount:integer;
end;
Problem is I don't know how to provide data to the mock for the test. Of course I can add an extra procedure, say AddValues(aAmount:integer), that does the job but in that case I would end up with this extra procedure in production too and I don't need it.
What is the best practice for this ?
I use Spring for Delphi framework
You can also use DSharp mocks (or Delphi Mocks).
This will be the setup code for DSharp (Delphi Mocks should be similar)
var
mockDBTable: Mock<IIDBTable>;
begin
mockDBTable.Setup.WillExecute.Once.WhenCalling.First;
mockDBTable.Setup.WillReturn(False).Exactly(5).WhenCalling.EOF;
mockDBTable.Setup.WillReturn(True).Once.WhenCalling.EOF;
mockDBTable.Setup.WillReturn(5).Once.WhenCalling.GetAmount;
mockDBTable.Setup.WillReturn(4).Once.WhenCalling.GetAmount;
mockDBTable.Setup.WillReturn(3).Once.WhenCalling.GetAmount;
mockDBTable.Setup.WillReturn(2).Once.WhenCalling.GetAmount;
mockDBTable.Setup.WillReturn(1).Once.WhenCalling.GetAmount;
mockDBTable.Setup.WillExecute.Exactly(5).WhenCalling.Next;
What you do here is specify what you expect to be called and what to be returned. This saves you from manually writing a mock class and feed it with data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With