我正在与Braintree API for .NET合作处理付款问题。他们的业务处理付款很好,API包装器可以直接使用。但是,经过仔细调查或更加剧烈的使用,提供的API包装器会很快失败;例如,它包含手动enum
s。我的问题来自单元测试使用此包装器的代码。
为了做到这一点,我基本上需要模拟我自己的'假的'Braintree网关,它会有一些已知的值,在请求时产生错误等等。我的攻击计划是覆盖Braintree的功能API包装器并将请求重新路由到本地内存中端点。然后我可以使用依赖注入在运行时链接正确的网关/包装器。
最初,它似乎正在游泳:尽管已经在API包装器中提交了软件工程的罪行,但我需要覆盖的每个方法都奇迹般地标记为virtual
。然而,这种情况急剧停止:API包装器中的几乎构造函数都标记为internal
。因此,我既不能继承这些类,也不能随意创建它们进行测试。
暂且不说:我找到internal
构造函数,以及合理地想要使用它们的原因。但是,我已经查看了这个的源代码,并且每个internal
构造函数只执行简单的属性赋值。因此,我很自然地声称应该遵循不同的编码习惯。
所以,我基本上有三个选择:
从头开始编写我自己的API包装。这显然是可行的,并且具有可以产生精心设计的基础设施的优势。然而,缺点太多,不能简单列出。
从API中提取源代码并将其包含在我的解决方案中。我可以将所有internal
构造函数更改为我需要的任何构造函数。缺点是我必须在每个后续的API包装器发布时重新更新所有这些更改。
为我需要在整个API包装器中使用的每个对象编写包装类。这具有不改变提供的源代码的优点;但缺点很大:基本上重写包装器中的每个类三次(接口,Braintree API包装适配器和可测试版本)。
不幸的是,所有这些都很糟糕。我觉得选项2可能是选项中最不好的选择,但它让我觉得很脏。有没有人已经解决了这个问题/编写了一个更好,更可测试的包装器?如果没有,我是否错过了可能的行动方案?如果没有,那三个选项中的哪一个似乎最不令人反感?
答案 0 :(得分:1)
答案 1 :(得分:1)
由于您没有测试他们的API,我会使用Facade模式。您不需要包装它们提供的所有,只需封装您正在使用的功能。这也为您提供了一个优势:如果您决定在将来放弃该API,您只需重新实现您的包装。