English 中文(简体)
如何对与第三方COM对象交互并实例化的代码进行单元测试?
原标题:
  • 时间:2008-09-16 08:53:33
  •  标签:

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

我知道我可能应该使用mock对象,但在这种情况下我该怎么做呢?我可以看到,当我只需要传递对一个已经存在的对象的引用,但我的一些例程自己实例化外部COM对象,然后有时将它们传递给另一个库中的其他外部COM对象时,这相对容易。

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

我会特别感谢Delphi的例子或工具,但也会很乐意提供更一般的建议和更高层次的解释。

谢谢

奥利弗

最佳回答

传统的方法是,客户端代码应该使用包装器,该包装器负责实例化COM对象。这样就可以很容易地模仿这个包装了。

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

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

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

问题回答

这归结为可测试性的设计。理想情况下,您不应该直接实例化这些COM对象,而是应该通过一层间接层来访问它们,该层可以被mock对象取代。

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

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

The wikipedia article has a good introduction to the subject Wikipedia artible





相关问题
热门标签