Delphi 如何对与第三方COM对象交互并实例化的代码进行单元测试?

Delphi 如何对与第三方COM对象交互并实例化的代码进行单元测试?,delphi,unit-testing,com,mocking,Delphi,Unit Testing,Com,Mocking,目前阻碍我全力投入单元测试的最大问题之一是,我编写的代码中有很大一部分严重依赖于来自不同来源的第三方COM对象,这些对象往往也会相互交互(如果您需要知道的话,我正在使用几个助手库为Microsoft Office编写外接程序) 我知道我可能应该使用mock对象,但在这种情况下,我应该怎么做呢?我可以看出,当我只需要传递一个对已经存在的对象的引用时,这是相对容易的,但我的一些例程本身实例化了外部COM对象,然后有时将它们从dif传递到其他外部COM对象新图书馆 这里的最佳实践方法是什么?我是否应该

目前阻碍我全力投入单元测试的最大问题之一是,我编写的代码中有很大一部分严重依赖于来自不同来源的第三方COM对象,这些对象往往也会相互交互(如果您需要知道的话,我正在使用几个助手库为Microsoft Office编写外接程序)

我知道我可能应该使用mock对象,但在这种情况下,我应该怎么做呢?我可以看出,当我只需要传递一个对已经存在的对象的引用时,这是相对容易的,但我的一些例程本身实例化了外部COM对象,然后有时将它们从dif传递到其他外部COM对象新图书馆

这里的最佳实践方法是什么?我是否应该让测试代码临时更改注册表中的COM注册信息,以便测试代码将实例化我的一个模拟对象?我是否应该注入修改过的类型库单元?还有哪些其他方法

我会特别感谢Delphi的示例或工具,但也会很高兴得到更一般的建议和更高层次的解释

谢谢


Oliver

它归结为“为可测试性而设计”。理想情况下,您不应该直接实例化那些COM对象,而应该通过一个可以被模拟对象替换的间接层来访问它们


现在,COM本身确实提供了一定程度的间接性,您可以提供一个模拟对象来替代真实对象,但我怀疑创建它会很痛苦,我怀疑您是否能从现有的模拟框架中获得很多帮助。

我将围绕您的第三方COM对象编写一个瘦包装器类,它能够o在单元测试情况下加载模拟对象,而不是实际的COM对象。我通常通过调用第二个构造函数传入模拟对象来实现这一点。普通构造函数只会像正常情况一样加载COM对象

维基百科的文章对这个主题有很好的介绍

传统方法认为客户端代码应该使用包装器,该包装器负责实例化COM对象。然后可以轻松地模拟该包装器

因为您的部分代码直接实例化COM对象,所以这并不适合。如果您可以更改该代码,您可以使用工厂模式:他们使用工厂创建COM对象。您可以模拟工厂以返回替代对象

对象是通过包装器访问还是通过原始COM接口访问取决于您。如果您选择模拟COM接口,请记住在模拟中插入IUnknown::QueryInterface,这样您就知道您已经模拟了所有接口,特别是当对象随后被传递给其他COM对象时


或者,检查该方法。我从未使用过它,但它可能会满足您的需要。

同意;而且由于与COM对象的所有交互(通过IDispatch进行的自动调用除外)都使用COM接口,您应该能够在模拟类中实现这些接口。