一般来说,我设计类时不需要出于测试目的访问私有(private)对象。一个 InternalsVisibleTo
也可以提供帮助。
但是,我目前正在处理一个代码库,该代码库有一些区域依赖于 [VSTS 中的私有(private)访问器机制]( http://msdn.microsoft.com/en-us/library/ms184807(VS.80).aspx)(即,使用 VSCodeGenAccessors
生成 *_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);
(是的,充满了反模式 - 但请不要开枪)
我有很多问题:
- 我希望能够弄清楚我需要哪些隐私
- 我不想调用对话(是的,我是个 CRaholic)
- 我不想在图片中涉及代码生成
所以我希望能够将上面的代码转换成如下形式:
var target = new ClassUnderTest();
IClassUnderTestInterface accessor = Shadow.Create<IClassUnderTestInterface>( target );
accessor.PrivateMethod();
Assert.True( accessor._privateMethodWasCalled);
accessor.PrivateProperty = 5;
Assert.Equal( accessor.PrivateProperty, 5);
我的测试程序集中只有以下接口(interface),没有生成代码或自定义构建步骤:-
interface IClassUnderTestInterface
{
int PrivateProperty {get; set;}
bool _privateMethodWasCalled {get; }
void PrivateMethod();
}
从那里,我将能够使用 CodeRush 或 Ctrl K M 在界面上生成新的阴影方法,只需一个按键。
缺少的一点是方法 I Shadow.Create<I>( Object o)
这将
1.生成实现接口(interface)的动态代理
1.验证对象o
要被包装的所有成员都由接口(interface)决定
1. bnous:正确管理表示字段的属性的转发(即 `_privateMethodWasCalled' 情况)
那么,有没有人知道一个库实现了这样的东西(或者觉得无聊到写它?)
一个明显的缺点是您直到运行时才知道接口(interface)是否与 ClassUnderTest 兼容,但这没关系,因为这仅用于测试。同样是 AIUI,私有(private)访问器机制也需要触发重新编译以不时同步内容。
或者我是否缺少更好的方法? (记住我不想一刀切地将所有私有(private)升级到内部或公共(public),也不想重写工作代码)
使用 xUnit.net、.NET 3.5;开放使用任何动态代理库或其他
最佳答案
您是否看过 Moq 或 Rhino 等模拟框架?在您的情况下,如果您愿意将需要测试的私有(private)更改为“ protected 虚拟”(这并不像内部公开那样糟糕),他们可以提供帮助。基本上,如果成员是虚拟的,那么模拟框架可以生成一个子类来记录调用了哪些成员。
关于.net - 用于测试私有(private)方法的非代码生成的转发垫片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1043899/