从Delphi项目中删除单例实例

Edu*_*ias 8 delphi mvp unit-testing

我正在努力使我的第一个项目可以进行单元测试.令人惊讶的是,我必须重新编写一些恶意编码风格的大脑.

这篇文章让我注意到单身人士是病态的骗子

我不是试图激进,但我习惯了一件神器,我不知道怎么能摆脱它

例:

initialization
  ModelFactory.RegisterFactoryMethod('standard.contasmovimento',
    function(AParam: Variant) : TModel
    begin
      result := TModelContasMovimento.Create(AParam);
    end);

end.
Run Code Online (Sandbox Code Playgroud)

ModelFactory是一个单例,在其单元上定义,是该单元的uses子句的一部分.

在我的MVP结构中,我在其自己的单元(1个1级单元)中定义了每个模型,视图和演示者.根据每个项目的需要,可以使用所有这些单元.因此,我将其用作零件目录,根据项目我将单元添加到项目中,它会自动注册并准备好从工厂使用.

为了解决单例问题我正在考虑将它们移动到框架类,因此我可以在一个点创建对象,然后可以使用依赖注入来传递框架对象.所有的工厂和其他环境都坐在那里:

TMyFramework = class
  FModelFactory: IModelFactory;
  FViewFactory: IViewFactory;
  FPresenterFactory: IPresenterFactory;

  property ModeFactory: IModelFactory read FModelFactory;
  ...
Run Code Online (Sandbox Code Playgroud)

我的意思是以一种我可以在测试单元中模拟它们的方式移除单身人士.随着单身人士的到位,我无法轻易将其移除以进行测试.

但这将使我放松每个单元的自动初始化,我依靠它来添加单元.我不想手动创建可用类的列表.

有办法解决这种情况吗?

Mar*_*ema 4

为了在不完全重写所有单例的情况下开始进行单元测试,我发现只需添加Free和重新Create单例的功能通常就足以让您开始。

假设单例是在初始化部分实例化的(禁止这些。它们是任何单元测试的祸根。单独注册和初始化单元。),您可以简单地将两个过程添加到接口部分。如果您不希望正常项目中的其他单元使用它们,请将它们放在条件定义之间:

{$IFDEF DUNIT}
procedure InstantiateMySingleton;
procedure FreeMySingleton;
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)

将初始化和终结部分中现在的代码移至这些过程的实现中,然后从初始化和终结中调用它们。

procedure InstantiateMySingleton;
begin
   // ...
end;

procedure FreeMySingleton;
begin
   // ...
end;

initialization
  InstantiateMySingleton;
finalization
  FreeMySingleton;
Run Code Online (Sandbox Code Playgroud)

完成此操作后,您可以开始在单元测试的设置和拆卸方法中使用 InstantiateMySingleton 和 FreeMySingleton。

然后您要做的就是确保创建和销毁单例不会泄漏内存,并且实际上每次都可以重复执行相同的功能结果。我发现有助于确保这一点的一件事是使用 GUI 运行器并运行整个测试套件两次(当然不退出 GUI!)。如果某些测试在第一次运行时成功而在第二次运行时失败,则表明您在单例的初始化或终结中遇到了问题。