正文

如何测试私有/受保护的方法? (译文) (二)2010-07-21 10:35:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/edwardguo/51518.html

分享到:

4.   测试私有方法

测试私有方法稍微复杂些,但我们可以利用System.Reflection。你可以利用反射动态的访问一个类型的方法,包括实例和静态的私有方法。要注意的是访问私有方法需要ReflectionPermission,但在开发机或BUILD机上运行单元测试不是问题。

假设我们要测试ClassLibrary1.MyObject类的MyPrivateMethod私有方法:

private string MyPrivateMethod(string strInput, DateTime dt, double

 dbl)

{

    return this.Name + ": " + strInput + ", " +

     dt.ToString() + ", " + dbl.ToString();

}

一种解决方法是建立一个UnitTestUtilities 工程包含一个UnitTestUtilities.Helper类,用于通过反射调用测试方法。

public static object RunStaticMethod(System.Type t, string strMethod,

 object [] aobjParams)

{

    BindingFlags eFlags =

     BindingFlags.Static | BindingFlags.Public |

     BindingFlags.NonPublic;

    return RunMethod(t, strMethod,

     null, aobjParams, eFlags);

} //end of method

public static object RunInstanceMethod(System.Type t, string strMethod,

 object objInstance, object [] aobjParams)

{

    BindingFlags eFlags = BindingFlags.Instance | BindingFlags.Public |

     BindingFlags.NonPublic;

    return RunMethod(t, strMethod,

     objInstance, aobjParams, eFlags);

} //end of method

private static object RunMethod(System.Type t, string

 strMethod, object objInstance, object [] aobjParams, BindingFlags eFlags)

{

    MethodInfo m;

    try

    {

        m = t.GetMethod(strMethod, eFlags);

        if (m == null)

        {

             throw new ArgumentException("There is no method '" +

              strMethod + "' for type '" + t.ToString() + "'.");

        }

                               

        object objRet = m.Invoke(objInstance, aobjParams);

        return objRet;

    }

    catch

    {

        throw;

    }

} //end of method

私有方法RunMethod利用反射时必须的参数,调用相关的被测试方法并返回值。这里有两个封装的方法RunStaticMethodRunInstanceMethod,分别针对静太方法和实例方法。

大概看一下这两个方法的代码,首先取得类型的MethodInfo,因为我们调用的是已经存在的方法,如果是空方法,则产生一个异常。一旦有了MethodInfo,我们就可以调用实例(如果是static,则为null)的私有方法,并传入参数数组。

我们可以在NUnit中这样使用:

 

 [Test] public void TestPrivateInstanceMethod()

{

    string strExpected = "MyName: Hello, 5/24/2004

     12:00:00 AM, 2.1";

    

    ClassLibrary1.MyObject objInstance

     = new MyObject("MyName");

   

    object obj =

     UnitTestUtilities.Helper.RunInstanceMethod(

     typeof(ClassLibrary1.MyObject), "MyPrivateMethod",

     objInstance, new object[3] {"Hello",

     new DateTime(2004,05,24), 2.1});

   

    string strActual = Convert.ToString(obj);

   

    Assert.AreEqual(strExpected,strActual);

}

标准

满足性

透明性

唯一的额外代码- UnitTestUtilities,不会包含在产品中一起发布。

范围

该方法中没有任何东西是仅依赖于调试模式。

简单性

该方法可以在一个单独调用中调用任何方法。利用UnitTestUtilities的唯一问题就是为RunInstanceMethodRunStaticMethod创建正确的参数(方法名、数据类型等)。因为方法是动态调用的,参数在编译时不会被检查。

 

5.   结论

虽然对私有方法的测试存在争论,至少我们现在知道如何进行测试了。我们可以通过包装基类建立一个派生类TesterClass用于测试其protected方法,通过UnitTestUtility帮助类利用反射可以测试类中的私有方法。所有这些技术都可利于提高测试覆盖率。


参考:

http://www.codeproject.com/csharp/TestNonPublicMembers.asp 

阅读(1997) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册