一般而言,我设计类的方式是不需要访问私有来进行测试。 InternalsVisibleTo
也可以提供帮助。
但是,我目前正在处理一个代码库,它有一些区域已经依赖于[VSTS中的私有访问器机制](http://msdn.microsoft.com/en-us/library/ms184807(VS.80).aspx)(即使用VSCodeGenAccessors
生成{{ 1}}具有使用反射转发的类,用于在类上调用*_Accessor
成员(以及可选的private
成员。)
所以我有类似的代码:
internal
(是的,充满反模式 - 但请不要射击信使)
我有很多问题:
所以我希望能够将上面的代码转换为:
ClassUnderTest target = new ClassUnderTest();
var accessor = ClassUnderTest_Accessor.AttachShadow( target );
accessor.PrivateMethod();
Assert.True( accessor._privateMethodWasCalled);
accessor.PrivateProperty = 5;
Assert.Equal( accessor.PrivateProperty, 5);
只有以下界面位于我的测试程序集中,并且没有生成代码或自定义构建步骤: -
var target = new ClassUnderTest();
IClassUnderTestInterface accessor = Shadow.Create<IClassUnderTestInterface>( target );
accessor.PrivateMethod();
Assert.True( accessor._privateMethodWasCalled);
accessor.PrivateProperty = 5;
Assert.Equal( accessor.PrivateProperty, 5);
从那里,我可以使用CodeRush或Ctrl K M在界面上生成新的阴影方法,只需要一次击键。
缺少的位将有一个方法interface IClassUnderTestInterface
{
int PrivateProperty {get; set;}
bool _privateMethodWasCalled {get; }
void PrivateMethod();
}
1.生成实现接口的动态代理
1.验证要包装的对象I Shadow.Create<I>( Object o)
是否具有接口指示的所有成员
1. bnous:正确管理代表字段的属性转发(即`_privateMethodWasCalled'案例)
那么,有没有人知道一个实现这样的东西的库(或者觉得无聊到写它?)
一个明显的缺点是你不知道界面是否在运行时不能与ClassUnderTest相提并论,但这没关系,因为这只适用于测试。另外,AIUI,私有访问器机制也需要触发重新编译以不时地同步内容。
或者有没有更好的方法我错过了? (记住我不想去内部或公共场所,并且不想重写工作代码)
使用xUnit.net,.NET 3.5;打开使用任何动态代理库或其他
答案 0 :(得分:1)
您是否看过像Moq或Rhino这样的模拟框架?在您的情况下,如果您愿意将需要测试的私有化更改为“受保护的虚拟”(这并不像内部公开那么糟糕),他们可以提供帮助。基本上,如果成员是虚拟的,那么模拟框架可以生成一个子类来记录成员被调用的内容。
答案 1 :(得分:1)
我最终绕过所有这些东西(InternalsVisibleTo
,单独的测试项目,测试引用,私有访问器,MSBuild Shadow任务/ publicize.exe在构建中随机失败,使用反射访问私有)通过合并测试主要项目并制作需要从测试internal
访问的任何内容。另请参阅xUnit.net Test Stripper [to remove test code embedded in binaries prior to deployment/shipping]
答案 2 :(得分:0)
这个neat trick可以使转发功能更加简洁,虽然它本质上仍然是手动的
此外,this answer涵盖了如何处理static
成员(但要求CLR4在我提出要求时没有发挥作用,并且在未将InternalsVisibleTo
带入的情况下不处理私有方法混合)。