背景

年龄大点的程序员都知道在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类库提取私有方法反射调用的方法的更多相关文章

  1. VS2010 F5调试时出现:“ 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常”解决

    VS2010 F5调试时出现 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常 两个解决方法:1) 打开项目属性,选择调试选项卡,将“启用非托管代码调试”一项钩上.2) 打开项目属性,选择调试选 ...

  2. 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)

    反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法)   创建Delegate (1).Delegate.CreateDelegate(Type, ...

  3. JavaSE复习日记 : 方法的调用和方法的重载

    /* * 方法的调用和方法重载 */ /* * 什么是方法? * 方法就是一个有名字的代码段; * 方法的调用: * 在方法里调用另外一个方法里面的东西就是方法调用; * 或者可以认为"另外 ...

  4. JNI C反射调用java方法

    前面记录了调用C的学习笔记,现在来记录一下C反射调用Java的笔记.JNI开发学习之调用C方法 Android开发中调用一个类中没有公开的方法,可以进行反射调用,而JNI开发中C调用java的方法也是 ...

  5. java动态载入指定的类或者jar包反射调用其方法

    序言 有时候.项目中会用到java动态载入指定的类或者jar包反射调用其方法来达到模块的分离,使各个功能之间耦合性大大减少,更加的模块化.代码利用率更高.模式中的代理模式就用到java的这一机制. 下 ...

  6. Spring AOP开发时如何得到某个方法内调用的方法的代理对象?

    Spring AOP开发时如何得到某个方法内调用的方法的代理对象? 问题阅读起来拗口,看代码 在方法中调用其他方法很常见,也经常使用,如果在一个方法内部调用其他方法,比如 public class U ...

  7. 对JAVA Bean使用PropertyDescriptor反射调用JAVA方法

    对于符合JAVA Bean规范的bean,调用其方法应优先使用java.beans.PropertyDescriptor获取Method进行方法调用,以获得更大的可维护性. 示比例如以下: NonCo ...

  8. springMVC在普通方法中调用service方法

    SpringContextUtil类 package com.common.util; import org.springframework.beans.BeansException;import o ...

  9. UnityTips:使用反射调用内部方法拓展编辑器

    大家都知道Unity是一个C/C++的游戏引擎,C#只是Unity提供的脚本层.因此大部分功能都是通过C#来调用底层的C++代码的.而一些朋友可能不知道的是,其实Unity的C#代码中也有很多方法是我 ...

随机推荐

  1. js模版引擎handlebars.js实用教程——另一种Helper用法

    返回目录 <!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content=" ...

  2. Spring Trasnaction管理(3)- 事务嵌套

    问题导读 Spring 如何管理嵌套的事务 Spring事务传播机制 Nested 和 RequireNew 有何区别 事务传播机制 事务的传播机制应该都比较熟悉 在日常开发中会遇到需要事务嵌套的情况 ...

  3. 爱上MVC~为CheckBoxFor和RadioButtonFor加个扩展方法吧(希望MVC5把这方法收纳——呵呵)

    回到目录 说在前 我都是喜欢把问题复杂化,还有总是喜欢把问题简单化,偷懒化,这也需就是一个程序员的追求吧,呵呵. 我不太喜欢重复的东西,当你看到页面上有一个以上相同的代码时,那可以说,你的代码有重构的 ...

  4. svn:previous operation has not finished

    svn提交遇到一个恶心的问题,cleanup也不行. 错误如下: Previous operation has not finished; run 'cleanup' if it was interr ...

  5. 用PHP访问数据库

    <?php //1造链接.面向对象 .方式对象方式 //把对象定个名字$db //MySQLi:数据扩展类.在MySQLi里做对象() //host:代表服务器地址也叫做本机[本机服务器loca ...

  6. 基于Oracle的SQL优化(社区万众期待 数据库优化扛鼎巨著)

    基于Oracle的SQL优化(社区万众期待数据库优化扛鼎巨著) 崔华 编   ISBN 978-7-121-21758-6 2014年1月出版 定价:128.00元 856页 16开 编辑推荐 本土O ...

  7. Tomcat源码阅读(二)初始化

    近来,我开始阅读tomcat的源码,感觉还挺清晰易懂:为了方便理解,我参考了网上的一些文章,把tomcat的组成归纳一下:整个tomcat的组成如下图所示: Tomcat在接收到用户请求时,将会通过以 ...

  8. ROC曲线与AUC值

    本文根据以下文章整理而成,链接: (1)http://blog.csdn.net/ice110956/article/details/20288239 (2)http://blog.csdn.net/ ...

  9. 记一次裸迁 MySQL 经历

    记一次裸迁MySQL经历 前言:博主企业有一台企业阿里云机器,因为安装了云锁,造成服务器动不动就给我所死服务器.(就是那种 chattr +i /bin/bash ,分分钟日死狗 )趁着周末,Boos ...

  10. 一次意外的X锁不阻塞问题

        最近有一个朋友问我一个关于给查询操作强制上X锁却不阻塞的问题.该查询写在一个存储过程中,代码如代码1所示: 1: create PROC [dbo].[GetCityOrders] 2: @c ...