6

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

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

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

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

谢谢,

奥利弗

4

3 回答 3

6

传统方法说您的客户端代码应该使用一个包装器,它负责实例化 COM 对象。然后可以轻松地模拟此包装器。

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

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

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

于 2008-09-16T09:10:44.160 回答
3

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

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

于 2008-09-16T09:01:15.197 回答
2

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

wikipedia article对Wikipedia artible这个主题有很好的介绍

于 2008-09-16T09:04:17.280 回答