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

StackOverflow https://stackoverflow.com/questions/70482

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

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

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

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

谢谢,

奥利弗

有帮助吗?

解决方案

传统方法认为您的客户端代码应该使用包装器,它负责实例化 COM 对象。然后这个包装器就可以很容易地被嘲笑。

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

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

或者,查看 共同对待类 方法。我从未使用过它,但它可能可以满足您的需求。

其他提示

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top