写了NUnit使用之HelloWorld后,又不知道该写什么了,好像NUnit就这样了.但我们有时又会为测试而抓狂,其实NUnit只是一个工具,写好的单元测试用例要遵循好的设计原则,如:ATRIP.这里就不过多解释了,转入正题.
对Private方法的测试并不是NUnit本身的功能,而是我们通过.net的反射机制执行private方法得到结果,再各期望值进行比较.所以这次要讲的重点在于.net反射的使用.虽然只是其中一点皮毛,但读者应该可以从中对反射有所了解.
首先定义一个类Calculator,有一个方法Add,实现简单的加法.这个就是我们的被测类.
接下来,要对这个类进行测试:
1
//
被测类,实现简单的加法
2
using
System;
3
![](http://img.e-com-net.com/image/product/93a7f0399a9049a3b82d13dcc4073372.gif)
4
namespace
PrivateMethodTest
5
![](http://img.e-com-net.com/image/product/8bf85857a9e14d23a651e7c8ef856bcc.gif)
{
6
public class Calculator
7![](http://img.e-com-net.com/image/product/437570a32a8e47669b1b8f34e2a85bac.gif)
{
8
private int Add(int a, int b)
9![](http://img.e-com-net.com/image/product/437570a32a8e47669b1b8f34e2a85bac.gif)
{
10
return a + b;
11
}
12
}
13
}
1
using
System;
2
using
System.Reflection;
3
using
NUnit.Framework;
4
![](http://img.e-com-net.com/image/product/93a7f0399a9049a3b82d13dcc4073372.gif)
5
namespace
PrivateMethodTest
6
![](http://img.e-com-net.com/image/product/8bf85857a9e14d23a651e7c8ef856bcc.gif)
{
7
[TestFixture]
8
public class CalculatorTest
9![](http://img.e-com-net.com/image/product/437570a32a8e47669b1b8f34e2a85bac.gif)
{
10
//对Add进行测试
11
[Test]
12
public void TestAdd()
13![](http://img.e-com-net.com/image/product/437570a32a8e47669b1b8f34e2a85bac.gif)
{
14
int expected = 3;
15![](http://img.e-com-net.com/image/product/b5ccfbfdc70d443ba19cbdc6a5005b86.gif)
16
Calculator cal = new Calculator();
17![](http://img.e-com-net.com/image/product/437570a32a8e47669b1b8f34e2a85bac.gif)
object result = InvokePMethod(typeof(PrivateMethodTest.Calculator),"Add",cal,new object[2]
{1,2});
18
19
Assert.AreEqual(expected, result);
20
}
21![](http://img.e-com-net.com/image/product/b5ccfbfdc70d443ba19cbdc6a5005b86.gif)
22
//辅助方法:调用其他类的私有方法
23
//InstanceClass:类的实例,Params:方法的参数实例
24
private object InvokePMethod(System.Type Type, string MethodName, object InstanceClass, object[] Params)
25![](http://img.e-com-net.com/image/product/437570a32a8e47669b1b8f34e2a85bac.gif)
{
26
//发现方法的属性 (Attribute) 并提供对方法元数据的访问(摘自:MSDN)
27
//这里方法的属性指方法的static,virtual,final等修饰,方法的参数,方法的返回值等详细信息
28
//最重要一点是通过MethodInfo可以调用方法(invoke)
29
MethodInfo Method;
30![](http://img.e-com-net.com/image/product/b5ccfbfdc70d443ba19cbdc6a5005b86.gif)
31
//指定被搜索成员的类型,NonPublic表示搜索非公有成员,Instance表示搜索实例成员(非static)
32
//所以下面这句表示搜索类型为非公有的实例成员
33
BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
34![](http://img.e-com-net.com/image/product/b5ccfbfdc70d443ba19cbdc6a5005b86.gif)
35
//Type为System.Reflection功能的根,也是访问元数据的主要方式。(摘自:MSDN)
36
//使用Type的成员获取关于类型声明的信息,如构造函数、方法、字段、属性 (Property)
37
//和类的事件,以及在其中部署该类的模块和程序集。(摘自:MSDN)
38
//Type是.net中反射的根源,就如java中的Class类.如果连类都没有,那么调用方法,得到属性,一切都无从入手.
39
//GetMethod:通过方法名和搜索方式得MethodInfo
40
Method = Type.GetMethod(MethodName, flags);
41![](http://img.e-com-net.com/image/product/b5ccfbfdc70d443ba19cbdc6a5005b86.gif)
42
//调用private方法:参数分别为类的实例和方法参数
43
object result = Method.Invoke(InstanceClass, Params);
44![](http://img.e-com-net.com/image/product/b5ccfbfdc70d443ba19cbdc6a5005b86.gif)
45
return result;
46
}
47
}
48
}
重点在于通过反射调用Private方法,得到运行结果,其他与测试Public方法并无二样。使用反射的步骤:
1.创建实例,Calculator cal = new Calculator()
2.得到类型(Type),即typeof(PrivateMethodTest.Calculator),名称空间+类名
3.得到方法(Method),即Type.GetMethod(MethodName,Flags)
4.调用方法(Invoke),即object result = Method.Invoke(InstanceClass, Params);
所以result的值为调用cal中的Add方法,传入两参数1和2得到的结果,再与期望的结果3进行比较.测试通过.
![1 1](http://img.e-com-net.com/image/product/b398c69ce4a34dfb8f2a514b6e404747.jpg)