从vs2010的UnitTestFramework类库提取私有方法反射调用的方法
背景
年龄大点的程序员都知道在vs2010中创建单元测试非常的简单,鼠标定位在方法名字,右键创建单元测试,就会创建一个测试方法,即使是在私有方法上也可以创建测试方法。
VS2010以后就没这么简单了,微软默认取消了这种快捷方式,安装 Unit Test Generator 插件也只能在公有方法上创建单元测试。为了方便的测试私有方法,我们需要一种反射调用私有成员的方法。这种现成的方法可以在网上找到不少,我这里是讲述如何从VS2010
的UnitTestFramework类库提取反射调用私有成员的方法。
VS2010私有方法单元测试分析
在vs2010里新建个测试类:
public class Class1
{
private string GetName(string name, int age)
{
return name + age;
}
}
Class1
创建单元测试
/// <summary>
///GetName 的测试
///</summary>
[TestMethod()]
[DeploymentItem("ClassLibrary1.dll")]
public void GetNameTest()
{
Class1_Accessor target = new Class1_Accessor(); // TODO: 初始化为适当的值
string name = string.Empty; // TODO: 初始化为适当的值
int age = ; // TODO: 初始化为适当的值
string expected = string.Empty; // TODO: 初始化为适当的值
string actual;
actual = target.GetName(name, age);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("验证此测试方法的正确性。");
}
Class1 Test
有这么一行 [DeploymentItem("ClassLibrary1.dll")],多了个 Class1_Accessor
使用ILSpy打开ClassLibrary1.dll看看

可以看出Class1_Accessor : BaseShadow ,实例化时调用了基类的构造方法,实例化一个privateObject并赋给了m_privateObject ,GetName方法就是调用了m_privateObject 的invoke获取返回值。
protected BaseShadow(PrivateObject privateTarget)
{
this.m_privateObject = privateTarget;
}
沿着 BaseShadow ->PrivateObject->PrivateType->RuntimeTypeHelper->Helper的顺序把相关的代码都保存下来,文章最后提供下载。

其中用到FrameworkMessages 的都是错误信息相关的,用到了资源文件。这里没有照搬而是把用到的几个信息敲了一遍,如下:
class FrameworkMessages
{
public static string PrivateAccessorMemberNotFound(string name)
{
return string.Format("The member specified ({0}) could not be found.You might need to regenerate your private accesscor the member may be private and defined on a base class." +
"If the latter is true,you need to pass the type that defines the member into PrivateObject's constructor", name);
} public static string AccessStringInvalidSyntax
{
get { return "Access string has invalid syntax."; }
} public static string PrivateAccessorConstructorNotFound
{
get { return "The constructor with the specified signature could not be found.You might need to regenerate your private accesscor the member may be private and defined on a base class." +
"If the latter is true,you need to pass the type that defines the member into PrivateObject's constructor"; }
} }
FrameworkMessages
用到的方法找齐了,写个测试用例,首先定义一个需要访问的类
public class DemoClass
{
public string Name { get; set; }
public int Age { get; set; }
public DemoClass():this("zeroes",)
{
} public DemoClass(string name, int age)
{
this.Name = name;
this.Age = age;
} private string PrivateMethod(DateTime time)
{
return "姓名:{0} 年龄:{1} 时间:{2}".FormatWith(this.Name, this.Age, time.ToString("yyyy"));
}
}
DemoClass
然后封装一个私有反射的帮助类
/// <summary>
/// 调用方法单元测试管理类
/// </summary>
public static class PrivateUnitTestUtil
{ /// <summary>
/// 调用私有方法
/// </summary>
/// <param name="t">要访问的类类型</param>
/// <param name="methodName">方法名字</param>
/// <param name="paras">参数</param>
/// <returns></returns>
public static object InvokeMethod(Type t, string methodName, params object[] paras)
{
var privateObject = new PrivateObject(t);
return privateObject.Invoke(methodName, paras);
} /// <summary>
/// 调用私有方法
/// </summary>
/// <param name="instance">要访问的类实例</param>
/// <param name="methodName">方法名字</param>
/// <param name="paras">参数</param>
/// <returns></returns>
public static object InvokeMethod(object instance, string methodName, params object[] paras)
{
var privateObject = new PrivateObject(instance);
return privateObject.Invoke(methodName, paras);
}
}
PrivateUnitTestUtil
在测试项目中调用
[TestClass]
public class PrivateUnitTestUtilTests
{
[TestMethod]
public void InvokeMethodTest()
{
var instance = new DemoClass();
instance.Name = "";
DateTime time = DateTime.Now;
var ret = (string) PrivateUnitTestUtil.InvokeMethod(instance, "PrivateMethod", time);
Assert.AreEqual(ret, "姓名:{0} 年龄:{1} 时间:{2}".FormatWith(instance.Name, instance.Age, time.Year));
}
}
PrivateUnitTestUtilTests
更多的调用方式可以慢慢补充,相关文件下载地址:http://download.csdn.net/detail/zbl131/9493247
从vs2010的UnitTestFramework类库提取私有方法反射调用的方法的更多相关文章
- VS2010 F5调试时出现:“ 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常”解决
VS2010 F5调试时出现 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常 两个解决方法:1) 打开项目属性,选择调试选项卡,将“启用非托管代码调试”一项钩上.2) 打开项目属性,选择调试选 ...
- 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)
反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法) 创建Delegate (1).Delegate.CreateDelegate(Type, ...
- JavaSE复习日记 : 方法的调用和方法的重载
/* * 方法的调用和方法重载 */ /* * 什么是方法? * 方法就是一个有名字的代码段; * 方法的调用: * 在方法里调用另外一个方法里面的东西就是方法调用; * 或者可以认为"另外 ...
- JNI C反射调用java方法
前面记录了调用C的学习笔记,现在来记录一下C反射调用Java的笔记.JNI开发学习之调用C方法 Android开发中调用一个类中没有公开的方法,可以进行反射调用,而JNI开发中C调用java的方法也是 ...
- java动态载入指定的类或者jar包反射调用其方法
序言 有时候.项目中会用到java动态载入指定的类或者jar包反射调用其方法来达到模块的分离,使各个功能之间耦合性大大减少,更加的模块化.代码利用率更高.模式中的代理模式就用到java的这一机制. 下 ...
- Spring AOP开发时如何得到某个方法内调用的方法的代理对象?
Spring AOP开发时如何得到某个方法内调用的方法的代理对象? 问题阅读起来拗口,看代码 在方法中调用其他方法很常见,也经常使用,如果在一个方法内部调用其他方法,比如 public class U ...
- 对JAVA Bean使用PropertyDescriptor反射调用JAVA方法
对于符合JAVA Bean规范的bean,调用其方法应优先使用java.beans.PropertyDescriptor获取Method进行方法调用,以获得更大的可维护性. 示比例如以下: NonCo ...
- springMVC在普通方法中调用service方法
SpringContextUtil类 package com.common.util; import org.springframework.beans.BeansException;import o ...
- UnityTips:使用反射调用内部方法拓展编辑器
大家都知道Unity是一个C/C++的游戏引擎,C#只是Unity提供的脚本层.因此大部分功能都是通过C#来调用底层的C++代码的.而一些朋友可能不知道的是,其实Unity的C#代码中也有很多方法是我 ...
随机推荐
- [HIMCM暑期班]第4课: 扑克牌问题
假设跟你玩这样一个游戏: 拿一副52张牌的扑克,洗均匀.每次展示一张牌,如果是红心或者方块,你就赢10块钱:如果是黑桃或者草花,你就输10块钱.你可以选择在任何时候终止此游戏.问如何确保利益最大化? ...
- redis系列-主从复制
redis自身提供了主从的机制,通过配置可以实现服务的备份(Master->Slave). 配置项 slaveof <masterip> <masterport> mas ...
- SQLServer数据库还原提示 数据库正在使用,无法获得独占访问权
还原数据库的时候提示下图的错误:
- 用scrollTop制作一个自动滚动公告栏
我们在浏览网页时,经常会看到会一些滚动的栏目,比如向上滚动的公告.新闻等.其实他们的制作都不难,只要学了基础的html.css.javascript就可以做出来,用JavaScript的scrollT ...
- javascript_basic_02之数据类型、分支结构
1.弱类型:声明无需指定数据类型,由值决定,查看变量数据类型:typeof(变量): 2.隐式转换:任何数据类型与string类型相加,结果为string类型: 3.显式(强制)转换: ①toStri ...
- Ubuntu14.04安装pip及配置
安装pip: wget https://bootstrap.pypa.io/get-pip.py --no-check-certificate sudo python get-pip.py 建立软连接 ...
- HTTP与AJAX深入揭秘,不使用AJAX实现页面无刷新
AJAX的原理是什么? 实际上就是发起HTTP请求,既然就是发起HTTP请求,那只要我们能够实现发起HTTP请求就可以在不使用AJAX的情况下实现相同的效果. 在前端有好多方式可以发起HTTP请求,比 ...
- 将 PAGE_VERIFY 数据库选项设置为 CHECKSUM
此规则检查 PAGE_VERIFY 数据库选项是否已设置为 CHECKSUM.为 PAGE_VERIFY 数据库选项启用 CHECKSUM 后,SQL Server 数据库引擎会在向磁盘中写入页面时计 ...
- C# LINQ需求实现演化
Linq是C#3.0引入的,在C#2.0实现从集合中过滤符合条件的记录实现方式. 假设有一个Book类,以及一个Book类的集合,现在需要从集合中查找出单价大于50的Book. 1.固定查询字段的实现 ...
- SQL PASS将于8月24日在北京中医药大学举办线下活动
活动主题:复制架构的实现和调优以及SQL Server BI在传统行业的应用 地点:北三环东路11号 北京中医药大学 白色的1号楼教学楼后楼5层511房间 时间:2013年8月24日 9:00-12: ...