delphi – 如何模拟另一个类负责实例化的类?

delphi – 如何模拟另一个类负责实例化的类?,第1张

概述请考虑以下代码: type TFoo1 = class public procedure DoSomething1; end; TFoo2 = class private oFoo1 : TFoo1; public procedure DoSomething2; procedure DoSomething3; constructor 请考虑以下代码:

type  TFoo1 = class  public    procedure DoSomething1;  end;  TFoo2 = class  private    oFoo1 : TFoo1;  public    procedure DoSomething2;    procedure DoSomething3;    constructor Create;    destructor Destroy; overrIDe;  end;procedure TFoo1.DoSomething1;begin  ShowMessage('TFoo1');end;constructor TFoo2.Create;begin  oFoo1 := TFoo1.Create;end;destructor TFoo2.Destroy;begin  oFoo1.Free;  inherited;end;procedure TFoo2.DoSomething2;begin  oFoo1.DoSomething1;end;procedure TFoo2.DoSomething3;var  oFoo1 : TFoo1;begin  oFoo1 := TFoo1.Create;  try    oFoo1.DoSomething1;  finally    oFoo1.Free;  end;end;

我正在为一个班级创建单元测试,我坚持下去.我的问题都是关于模拟对象和我应该使用的设计模式的最佳方法.我是单元测试的类不是由我创建的.

>在下面的示例中,我需要模拟Foo1,因为它向我在单元测试期间无法调用的Web服务发送请求.但是Foo1是由TFoo2构造函数创建的,我无法模仿它.在这种情况下我该怎么办?我应该修改TFoo2构造函数来接受像这样的Foo1对象吗?

constructor TFoo2.Create(aFoo1 : TFoo1)begin  oFoo1 := aFoo1;end;

是否有一种设计模式表明我们需要传递一个类所依赖的所有对象,如上面的例子?
>方法TFoo2.DoSomething3创建Foo1对象然后释放它.我是否还应修改该代码以传递Foo1对象?

procedure TFoo2.DoSomething3(aFoo1 : TFoo1);begin  aFoo1 := aFoo1.DoSomething1;end;

>是否有任何设计模式支持我提出的建议?如果是这样,我可以告诉我工作的公司的所有开发人员,我们需要遵循XXX模式,以便更容易进行单元测试.

解决方法 如果你不能模拟TFoo1的创建,那么你就不能模拟TFoo1.现在,TFoo2负责创建TFoo1的所有实例,但如果这不是TFoo2的主要目的,那么这确实会使单元测试变得困难.

正如您所建议的那样,一种解决方案是将TFoo2传递给它所需的任何TFoo1实例.这可能使您已调用TFoo2方法的所有当前代码复杂化.另一种方法,即对单元测试更友好,是为TFoo1提供工厂.工厂可以像函数指针一样简单,也可以是整个类.在Delphi中,元类也可以作为工厂.在构造时将工厂传递给TFoo2,每当TFoo2需要TFoo1实例时,它就可以调用工厂.

要减少对其余代码的更改,可以使工厂参数在TFoo2构造函数中具有默认值.然后您不必更改应用程序代码.只需更改单元测试代码即可提供非默认的工厂参数.

无论你做什么,你都需要让TFoo1.DoSomething1成为虚拟的,否则嘲笑将是徒劳的.

使用元类,您的代码可能如下所示:

type  TFoo1 = class    procedure DoSomethign1; virtual;  end;  TFoo1Class = class of TFoo1;  TFoo2 = class  private    oFoo1 : TFoo1;    FFoo1Factory: TFoo1Class;  public    constructor Create(AFoo1Factory: TFoo1Class = nil);  end;constructor TFoo2.Create;begin  inherited Create;  FFoo1Factory := AFoo1Factory;  if not Assigned(FFoo1Factory) then    FFoo1Factory := TFoo1;  oFoo1 := FFoo1Factory.Create;end;

现在,您的单元测试代码可以提供TFoo1的模拟版本,并在创建TFoo2时传递它:

type  TMockFoo1 = class(TFoo1)    procedure DoSomething1; overrIDe;  end;procedure TMockFoo1.DoSomething1;begin  // Todo: Pretend to access Web serviceend;procedure TestFoo2;var  Foo2: TFoo2;begin  Foo2 := TFoo2.Create(TMockFoo1);end;

许多元类的例子为基类提供了一个虚拟构造函数,但这并不是绝对必要的.如果需要虚拟调用构造函数,则只需要一个虚拟构造函数 – 如果后代构造函数需要使用基类尚未执行的构造函数参数.如果后代(TMockFoo1,在这种情况下)与其祖先完成所有相同的事情,那么构造函数不需要是虚拟的. (还要记住,AfterConstruction已经是虚拟的,所以这是让后代在不需要虚拟构造函数的情况下进行额外 *** 作的另一种方法.)

总结

以上是内存溢出为你收集整理的delphi – 如何模拟另一个类负责实例化的类?全部内容,希望文章能够帮你解决delphi – 如何模拟另一个类负责实例化的类?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1251430.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存