我正在使用Braintree API for .NET来处理付款.他们的业务处理付款很好,API包装器可以直接使用.但是,经过仔细调查或更加剧烈的使用,提供的API包装器会很快失败; 例如,它包含手卷enum.我的问题来自单元测试使用此包装器的代码.
为了做到这一点,我基本上需要模拟我自己的'假'Braintree网关,其中会有一些已知值,在请求时产生错误等.我的攻击计划是覆盖Braintree API包装器的功能和将请求重新路由到本地内存中端点.然后我可以使用依赖注入在运行时链接正确的网关/包装器.
最初,它似乎在游泳:尽管在API包装器中已经犯了软件工程的罪,但我需要覆盖的每一种方法都奇迹般地被标记出来virtual.但是,这种情况突然停止了:API包装器中的几乎构造函数都被标记了internal.因此,我既不能继承这些类,也不能随意创建它们以进行测试.
旁白:我理解internal构造函数,以及合理地想要使用它们的原因.但是,我已经查看了这个的源代码,并且每个internal构造函数只执行简单的属性赋值.因此,我很自然地声称应该遵循不同的编码习惯.
所以,我基本上有三个选择:
从头开始编写我自己的API包装器.这显然是可行的,并且具有可以产生精心设计的基础设施的优势.然而,缺点太多,无法简要列出.
从API中提取源代码并将其包含在我的解决方案中.我可以将所有internal构造函数更改为我需要使它们工作的任何内容.缺点是我必须在每个后续的API包装器发布时重新更新所有这些更改.
为我需要在整个API包装器中使用的每个对象编写包装类.这具有不改变提供的源代码的优点; 但缺点很大:基本上重写包装器中的每个类三次(接口,Braintree API包装适配器和可测试版本).
不幸的是,所有这些都很糟糕.我觉得选项2可能是选项中最不好的选择,但它让我觉得很脏.有没有人已经解决了这个问题/编写了一个更好,更可测试的包装器?如果没有,我是否错过了可能的行动方案?如果没有,这三个选项中的哪一个似乎最不令人反感?
有没有办法通过反射执行"内部"代码?
这是一个示例程序:
using System;
using System.Reflection;
namespace ReflectionInternalTest
{
class Program
{
static void Main(string[] args)
{
Assembly asm = Assembly.GetExecutingAssembly();
// Call normally
new TestClass();
// Call with Reflection
asm.CreateInstance("ReflectionInternalTest.TestClass",
false,
BindingFlags.Default | BindingFlags.CreateInstance,
null,
null,
null,
null);
// Pause
Console.ReadLine();
}
}
class TestClass
{
internal TestClass()
{
Console.WriteLine("Test class instantiated");
}
}
}
Run Code Online (Sandbox Code Playgroud)
创建一个测试类通常是完美的,但是当我尝试通过反射创建一个实例时,我得到一个missingMethodException错误,说它无法找到构造函数(如果你尝试从程序集外部调用它会发生什么).
这是不可能的,还是我可以做一些解决方法?