我正在使用适用于 .NET 的 Braintree API 来处理付款。他们的业务在处理付款方面做得很好,API 包装器可以直接使用。但是,提供的 API 包装器在仔细调查或使用更频繁时开始迅速失效;例如,它包含 hand-rolled enum
s。我的问题来自对使用此包装器的代码进行单元测试。
为了做到这一点,我基本上需要模拟我自己的“假”Braintree 网关,其中包含一些已知值,在请求时生成错误等。我的攻击计划是覆盖 Braintree API 包装器的功能,并将请求重新路由到本地内存端点。然后我可以使用依赖注入在运行时链接正确的网关/包装器。
最初,它似乎很顺利:尽管在 API 包装器中犯了违反软件工程的罪,但我需要覆盖的每个方法都被奇迹般地标记为virtual
. 然而,这戛然而止:几乎 API 包装器中的构造函数被标记为internal
. 因此,我既不能继承这些类,也不能随心所欲地创建它们来存储以进行测试。
顺便说一句:我了解internal
构造函数,以及人们合法地想要使用它们的原因。但是,我查看了它的源代码,每个internal
构造函数只执行微不足道的属性分配。因此,我很乐意声称应该遵循不同的编码实践。
所以,我基本上只剩下三个选择:
从头开始编写我自己的 API 包装器。这显然是可行的,并且具有可以产生精心设计的基础设施的优势。然而,缺点太多了,无法简要列出。
从 API 中提取源代码并将其包含在我的解决方案中。我可以将所有
internal
构造函数更改为使它们工作所需的任何内容。缺点是我必须在每个后续 API 包装器发布时重新更新所有这些更改。为我需要在整个 API 包装器中使用的每个对象编写包装器类。这样做的好处是不改变提供的源代码;但是,缺点很大:基本上将包装器中的每个类都重写了 3 次(一个接口、一个 Braintree API 包装器适配器和一个可测试的版本)。
不幸的是,所有这些都很糟糕。我觉得选项 2 可能是最不糟糕的选项,但它让我觉得很脏。有没有人已经解决了这个问题/写了一个更好、更可测试的包装器?如果没有,我是否错过了可能的行动方案?如果不是,这三个选项中的哪一个看起来最不令人反感?