hBifTs

山自高兮水自深!當塵霧消散,唯事實留傳.荣辱不惊, 看庭前花开花落; 去留随意, 望天上云展云舒.

导航

增强NUnit的单元测试功能...

Posted on 2004-04-07 18:19  hbiftsaa  阅读(2699)  评论(9编辑  收藏  举报

muddle的"在单元测试中,如何测试非Public的对象"中,他提到了一种方法,就是使用预编译的方法..
但是我觉得使用那种方法太过于麻烦,于是在其评论中提到了使用Reflection的方法.但是有人提出了质疑..
于是,我写了一个简单的使用Reflection的TestHelper...由于Sourceforge我现在上不去,得不到NUnit的源代码,故未把此功能加入进去(自己看完了文章后再加也不迟)..


1,对于public class中的private方法.

//Assembly名称:  TestForTReflection
//namespace名称: TestForTReflection
 public class Class2
 {
  private void PrivateRun(int i)
  {
   Console.WriteLine("PrivateRun");
   Console.WriteLine(i);
  }
 }

我们先生成Class2的对象.obj,
   Type types = obj.GetType();
   MethodInfo method = types.GetMethod("PrivateRun",BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,null,new object[]{typeof(int)},null);
通过Type.GetMethod重载的方法得到我们想要得到的函数的MethodInfo,注意加红的代码.
如果我们要得到非public方法,必需要有BindingFlags.NonPublic 这行..
   return method.Invoke(obj,new object[]{234});
然后,得到后,我们调用它 酱紫就完成了private函数的调用了

2,对于private class

//Assembly名称:  TestForTReflection
//namespace名称: TestForTReflection
 class Class3{
  public Class3(int i){
   Console.WriteLine("Constractor" + i);
  }
  private void PrivateRun(int i)
  {
   Console.WriteLine("PrivateRun");
   Console.WriteLine(i);
  }
 }
这里,由于class为private,所以我们通过使用Assembly得到它的Type:
   Assembly asm = Assembly.Load("TestForTReflection");
   Type types = asm.GetType("TestForTReflection.Class3",true,true);
   object obj = Activator.CreateInstance(types,new object[]{234},null);
这里,obj就是最后Class3的对象.可以使用 obj.GetType()来看看:P


这里把做的TestHelper和其TestCase直接贴出来吧:P

namespace TestHelper
{
 public class Helper
 {
  public Helper()
  {
  }

  public static object Create(string assemblyName,string typeName,object[] args){
   Assembly asm = Assembly.Load(assemblyName);
   Type types = asm.GetType(typeName,true,true);
   return Activator.CreateInstance(types,args,null);
  }

  public static object InvokeMethod(object obj,string methodName,object[] args){
   Type types = obj.GetType();
   Type[] argtypes = new Type[args.Length];
   for(int i=0;i<args.Length;i++){
    argtypes[i] = args[i].GetType();
   }
   MethodInfo method = types.GetMethod(methodName,BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,null,argtypes,null);
   return method.Invoke(obj,args);
  }
 }
}

TestCase:

  [Test] public void Testss(){
   object obj = TestHelper.Helper.Create("TestForTReflection","TestForTReflection.Class3",new object[]{2});
   TestHelper.Helper.InvokeMethod(obj,"PrivateRun",new object[]{456});
  }



好了,现在SF.NET上去了,下载了源代码,加了上面的这个功能:P
完成后的NUnit.Framework.dll文件在这里下载:
NUnit.Framework.dll
使用NUnit.Framework.Helper类就OK了.
源代码就没加进去了,自己完全可以搞得定哦~