I want to test the simplest case : testing a mocked strategy object. (look at : Strategy pattern).
If I create a TMock<T>
in the TTestCase.setUp
methods and store it in a TTestCase
instance attribute, then should I free/NIL the mock variable in the tearDown
method?
The mock := NIL
does not compile:
[dcc32 Error] TestUnit2.pas(44): E2010 Incompatible types: 'Delphi.Mocks.TMock<T>' and 'Pointer'.
The mock.free
runs without any error, but I'm not sure I should call it. The mock released when the process exits its scope (after test case destructor).
Should I call/set anything?
The code:
Unit2.pas:
unit Unit2;
interface
type
TPartClass = class
public
function foo( x_ : integer ) : integer; virtual;
end;
TMainClass = class
private
fPart : TPartClass;
public
constructor create( part_ : TPartClass );
function bar( x_ : integer ) : integer;
end;
implementation
function TPartClass.foo( x_ : integer ) : integer;
begin
result := x_ shl 1;
end;
constructor TMainClass.create( part_ : TPartClass );
begin
inherited create;
fPart := part_;
end;
function TMainClass.bar( x_ : integer ) : integer;
begin
result := fPart.foo( x_ );
end;
TestUnit2.pas:
unit TestUnit2;
interface
uses
Delphi.Mocks, TestFramework, Unit2;
type
TTestTMainClass = class(TTestCase)
strict private
fPartClass : TMock<TPartClass>;
FMainClass: TMainClass;
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure Testbar;
end;
implementation
procedure TTestTMainClass.SetUp;
begin
fPartClass := TMock<TPartClass>.create;
FMainClass := TMainClass.Create( fPartClass );
end;
procedure TTestTMainClass.TearDown;
begin
FMainClass.Free;
FMainClass := NIL;
//fPartClass.Free;
//fPartClass := NIL;
end;
procedure TTestTMainClass.Testbar;
var
ReturnValue: Integer;
x_: Integer;
begin
fPartClass.Setup.WillReturn( 10 ).When.foo( 5 );
x_ := 5;
ReturnValue := FMainClass.bar(x_);
checkTRUE( returnValue = 10 );
end;
You should always cleanup everything in TearDown that you created during SetUp. Even though things might be cleaned up later it is good practice and will enable you to look for resource leaks while unit testing.
Since TMock<T>
is a record that internally holds interfaces you need to make sure those are cleaned up after the test run although they might be overridden by the next SetUp or when the testcase instance gets destroyed.
That is what .Free is for (despite the comment in the source)
This is even more important once you do more complex things with the mock as it might keep things alive or point to invalid references after the test. I have seen some bad crashes at the end of test applications that did not clean up their mocks.