如何测试被测对象销毁后引用可能导致的内存泄漏(DUnitX,Spring4D 1.2.2)
How to test possible memory leaks caused by references after the destruction of the tested object (DUnitX, Spring4D 1.2.2)
TMyClass
包含两个引用。对 IList<integer>
的引用和对 IMyInterface
的引用。 IList<integer>
的模拟是没有必要的。该框架可能经过良好测试,行为可预测,因此我可以将其视为数据对象。但是 IMyInterface
是一个未经测试的服务,所以我应该在单元测试中模拟它。
我想检查内存泄漏,所以我想在主题销毁后测试引用的 RefCount-s 的修改。
IList<integer>
的 'RefCount' 以正确的方式更改。但我不能对模拟的 IMyInterface
说同样的话(在我的解决方案中)。我如何测试引用不会导致内存泄漏?或者像这样的测试是一个集成测试,我应该总是用真实的实例来测试它吗?
unit Unit1;
interface
uses
DUnitX.TestFramework
, Spring.Collections
, Spring.Mocking
;
type
IMyInterface = interface ( IInvokable )
['{76B13784-6CCF-4A87-882C-E624F003B082}']
procedure foo;
end;
TMyClass = class
private
fList : IList<integer>;
fMyInterface : IMyInterface;
public
constructor Create( list_ : IList<integer>; myInterface_ : IMyInterface );
end;
[TestFixture]
TMyClassTest = class
protected
function getInterfaceRefCount( const interface_ : IInterface ) : integer;
public
[Test]
procedure listRefCountTest;
[Test]
procedure myInterfaceRefCountTest;
end;
implementation
uses
System.SysUtils
;
constructor TMyClass.Create( list_ : IList<integer>; myInterface_ : IMyInterface );
begin
inherited Create;
fList := list_;
fMyInterface := myInterface_;
end;
function TMyClassTest.getInterfaceRefCount( const interface_ : IInterface ) : integer;
begin
result := ( interface_ as TInterfacedObject ).RefCount;
end;
procedure TMyClassTest.listRefCountTest;
var
list : IList<integer>;
myInterfaceMock : Mock<IMyInterface>;
myClass : TMyClass;
listRefCount : integer;
begin
list := TCollections.CreateList<integer>;
myClass := TMyClass.Create( list, myInterfaceMock );
try
listRefCount := getInterfaceRefCount( list );
finally
FreeAndNIL( myClass );
end;
Assert.AreEqual( listRefCount-1, getInterfaceRefCount( list ) );
end;
procedure TMyClassTest.myInterfaceRefCountTest;
var
list : IList<integer>;
myInterfaceMock : Mock<IMyInterface>;
myClass : TMyClass;
myInterfaceRefCount : integer;
begin
list := TCollections.CreateList<integer>;
myClass := TMyClass.Create( list, myInterfaceMock );
try
myInterfaceRefCount := getInterfaceRefCount( myInterfaceMock.Instance );
finally
FreeAndNIL( myClass );
end;
Assert.AreEqual( myInterfaceRefCount-1, getInterfaceRefCount( myInterfaceMock.Instance ) );
end;
initialization
TDUnitX.RegisterTestFixture(TMyClassTest);
end.
内存泄漏检查不需要显式完成 - 我建议为此使用 https://github.com/shadow-cs/delphi-leakcheck - 它可以与 DUnit 或 DUnitX 无缝集成,并在发生泄漏时自动为您提供所需的所有信息(与仅告诉您“存在 x 字节泄漏”相反,开箱即用的 DUnit 通过简单地比较 运行 测试前后分配的字节)
TMyClass
包含两个引用。对 IList<integer>
的引用和对 IMyInterface
的引用。 IList<integer>
的模拟是没有必要的。该框架可能经过良好测试,行为可预测,因此我可以将其视为数据对象。但是 IMyInterface
是一个未经测试的服务,所以我应该在单元测试中模拟它。
我想检查内存泄漏,所以我想在主题销毁后测试引用的 RefCount-s 的修改。
IList<integer>
的 'RefCount' 以正确的方式更改。但我不能对模拟的 IMyInterface
说同样的话(在我的解决方案中)。我如何测试引用不会导致内存泄漏?或者像这样的测试是一个集成测试,我应该总是用真实的实例来测试它吗?
unit Unit1;
interface
uses
DUnitX.TestFramework
, Spring.Collections
, Spring.Mocking
;
type
IMyInterface = interface ( IInvokable )
['{76B13784-6CCF-4A87-882C-E624F003B082}']
procedure foo;
end;
TMyClass = class
private
fList : IList<integer>;
fMyInterface : IMyInterface;
public
constructor Create( list_ : IList<integer>; myInterface_ : IMyInterface );
end;
[TestFixture]
TMyClassTest = class
protected
function getInterfaceRefCount( const interface_ : IInterface ) : integer;
public
[Test]
procedure listRefCountTest;
[Test]
procedure myInterfaceRefCountTest;
end;
implementation
uses
System.SysUtils
;
constructor TMyClass.Create( list_ : IList<integer>; myInterface_ : IMyInterface );
begin
inherited Create;
fList := list_;
fMyInterface := myInterface_;
end;
function TMyClassTest.getInterfaceRefCount( const interface_ : IInterface ) : integer;
begin
result := ( interface_ as TInterfacedObject ).RefCount;
end;
procedure TMyClassTest.listRefCountTest;
var
list : IList<integer>;
myInterfaceMock : Mock<IMyInterface>;
myClass : TMyClass;
listRefCount : integer;
begin
list := TCollections.CreateList<integer>;
myClass := TMyClass.Create( list, myInterfaceMock );
try
listRefCount := getInterfaceRefCount( list );
finally
FreeAndNIL( myClass );
end;
Assert.AreEqual( listRefCount-1, getInterfaceRefCount( list ) );
end;
procedure TMyClassTest.myInterfaceRefCountTest;
var
list : IList<integer>;
myInterfaceMock : Mock<IMyInterface>;
myClass : TMyClass;
myInterfaceRefCount : integer;
begin
list := TCollections.CreateList<integer>;
myClass := TMyClass.Create( list, myInterfaceMock );
try
myInterfaceRefCount := getInterfaceRefCount( myInterfaceMock.Instance );
finally
FreeAndNIL( myClass );
end;
Assert.AreEqual( myInterfaceRefCount-1, getInterfaceRefCount( myInterfaceMock.Instance ) );
end;
initialization
TDUnitX.RegisterTestFixture(TMyClassTest);
end.
内存泄漏检查不需要显式完成 - 我建议为此使用 https://github.com/shadow-cs/delphi-leakcheck - 它可以与 DUnit 或 DUnitX 无缝集成,并在发生泄漏时自动为您提供所需的所有信息(与仅告诉您“存在 x 字节泄漏”相反,开箱即用的 DUnit 通过简单地比较 运行 测试前后分配的字节)