【问题标题】:Non-code-generated forwarding shim for testing private methods用于测试私有方法的非代码生成转发 shim
【发布时间】:2011-06-22 21:00:01
【问题描述】:

一般来说,我设计类的方式是为了测试目的不需要访问私有数据。 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 K M 在界面上生成新的阴影方法,只需要一个按键。

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

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

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

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

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

【问题讨论】:

    标签: .net testing reflection xunit.net internalsvisibleto


    【解决方案1】:

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

    【讨论】:

    • 有趣的想法。尽管 IMO ...但是虚拟是可能的,并且可能有助于实现它[当然仍然通过 LazyWeb]。谢谢你的主意。 (当天没有+1,但会在适当的时候跟进!)
    • 当然,关键是我正在寻找这里的实现......
    【解决方案2】:

    我最终通过将测试合并到所有这些东西(InternalsVisibleTo,单独的测试项目,测试引用,私有访问器,MSBuild Shadow 任务/publicize.exe 在构建中随机失败,使用反射访问私有)路由主要项目并制作任何需要从测试中访问的东西internal)。另见xUnit.net Test Stripper [to remove test code embedded in binaries prior to deployment/shipping]

    【讨论】:

    【解决方案3】:

    这个neat trick可以让转发功能更加简洁,虽然它本质上还是手动的

    此外,this answer 还介绍了如何处理 static 成员(但需要 CLR4,在我提出问题时它还没有发挥作用,并且不处理私有方法而不将 InternalsVisibleTo 加入其中)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-17
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      相关资源
      最近更新 更多