2

一般来说,我设计类的方式是为了测试目的不需要访问私有数据。安InternalsVisibleTo也可以帮忙。

但是,我目前正在处理一个代码库,该代码库有一些区域已经依赖于 [VSTS 中的私有访问器机制]( 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);

(是的,充满了反模式——但请不要向信使开枪)

我对此有很多问题:

  1. 我希望能够澄清我需要哪些隐私
  2. 我不想调用对话框(是的,我是一个 CRaholic)
  3. 我不想在图片中涉及代码生成

所以我希望能够将上面的代码转换为:

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 IClassUnderTestInterface
{
   int PrivateProperty {get; set;}
   bool _privateMethodWasCalled {get; }
   void PrivateMethod();
}

从那里,我可以使用 CodeRush 或 Ctrl KM 在界面上生成新的阴影方法,只需一个按键。

缺少的部分将有一个方法,该方法I Shadow.Create<I>( Object o)将 1. 生成实现接口的动态代理 1. 验证o要包装的对象是否具有接口指定的所有成员 1. bnous:管理表示字段的属性的转发(即, `_privateMethodWasCalled' 案例)正确

那么,有没有人知道一个实现这样的东西的库(或者觉得写它很无聊?)

一个明显的缺点是,您直到运行时才知道接口是否与 ClassUnderTest 不兼容,但这没关系,因为这仅用于测试。同样 AIUI,私有访问器机制也需要触发重新编译以不时同步内容。

或者有没有更好的方法我错过了?(请记住,我不想将 al privates 全面升级为内部或公共,也不想重写工作代码)

使用 xUnit.net、.NET 3.5;开放使用任何动态代理库或其他

4

3 回答 3

1

你看过像 Moq 或 Rhino 这样的模拟框架吗?在您的情况下,如果您愿意将需要测试的私有更改为“受保护的虚拟”(内部公开并没有那么糟糕),他们可以提供帮助。基本上,如果成员是虚拟的,那么 mocking 框架可以生成一个子类来记录调用了哪些成员。

于 2009-06-26T12:34:54.663 回答
1

我最终InternalsVisibleTo通过将测试合并到主项目并制作任何东西来绕过所有这些东西(单独的测试项目、测试引用、私有访问器、MSBuild Shadow 任务/publicize.exe 在构建中随机失败,使用反射访问私有)需要从测试中访问internal)。另请参阅xUnit.net Test Stripper [在部署/交付之前删除嵌入在二进制文件中的测试代码]

于 2009-11-26T16:38:48.763 回答
0

这个巧妙的技巧可以使转发功能更加简洁,尽管它本质上仍然是手动的

此外,这个答案涵盖了如何处理static成员(但需要 CLR4,在我提出问题时它还没有发挥作用,并且不处理私有方法而不InternalsVisibleTo涉及混合)。

于 2010-02-12T09:27:13.823 回答