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 – 如何模拟另一个类负责实例化的类?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)