.net - 用于测试私有(private)方法的非代码生成的转发垫片

标签 .net testing reflection xunit.net internalsvisibleto

一般来说,我设计类时不需要出于测试目的访问私有(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);

(是的,充满了反模式 - 但请不要开枪)

我有很多问题:

  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),没有生成代码或自定义构建步骤:-

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/

相关文章:

c# - Linq-to-sql 查询中的动态类型

php - 通过引用将参数可移植地传递给 PHP 的 ReflectionMethod::invokeArgs

c# - Entity Framework : how to replace a significant part of a lambda query in c# by using an ExpressionVisitor

c# - 如何将 SecureString 转换为 System.String?

javascript - 与 Chai 的 Deep AND Close 数组相等

perl - 如何测试使用 File::ShareDir 的模块?

c# - 调用具有反射和配置依赖项的 DLL

c# - 毫无意义的单元测试

.net - System.Transactions 的实际用途是什么?

ruby-on-rails - 当我想测试我的助手类时,无法在 ActionView::TestCase 中使用 flash