测试私有静态方法抛出MissingMethodException

时间:2015-02-16 17:54:49

标签: c# unit-testing privateobject.invoke

我有这堂课:

public class MyClass
{
   private static int GetMonthsDateDiff(DateTime d1, DateTime d2)
   {
     // implementatio
   }
}

现在我正在为它实施单元测试。 由于该方法是私有的,我有以下代码:

MyClass myClass = new MyClass();
PrivateObject testObj = new PrivateObject(myClass);
DateTime fromDate = new DateTime(2015, 1, 1);
DateTime toDate = new DateTime(2015, 3, 17);
object[] args = new object[2] { fromDate, toDate };
int res = (int)testObj.Invoke("GetMonthsDateDiff", args); //<- exception

mscorlib.dll中出现“System.MissingMethodException”类型的异常,但未在用户代码中处理 其他信息:尝试访问缺少的成员。

我做错了什么?该方法存在..

5 个答案:

答案 0 :(得分:21)

这是一种静态方法,因此请使用PrivateType代替PrivatObject来访问它。

请参阅PrivateType

答案 1 :(得分:8)

使用以下代码与PrivateType

MyClass myClass = new MyClass();
PrivateType testObj = new PrivateType(myClass.GetType());
DateTime fromDate = new DateTime(2015, 1, 1);
DateTime toDate = new DateTime(2015, 3, 17);
object[] args = new object[2] { fromDate, toDate };
(int)testObj.InvokeStatic("GetMonthsDateDiff", args)

答案 2 :(得分:3)

Invoke方法是无法找到的方法。 Object类没有Invoke方法。我想您可能正在尝试使用this Invoke,这是System.Reflection的一部分。

您可以像这样使用它,

var myClass = new MyClass();
var fromDate = new DateTime(2015, 1, 1);
var toDate = new DateTime(2015, 3, 17);
var args = new object[2] { fromDate, toDate };

var type = myClass.GetType();
// Because the method is `static` you use BindingFlags.Static 
// otherwise, you would use BindingFlags.Instance 
var getMonthsDateDiffMethod = type.GetMethod(
    "GetMonthsDateDiff",
    BindingFlags.Static | BindingFlags.NonPublic);
var res = (int)getMonthsDateDiffMethod.Invoke(myClass, args);

然而,您不应该尝试测试private方法;它太具体而且容易改变。您应该将publicDateCalculator设为MyClass中的私有,或者将其设为internal,这样您只能在程序集中使用。

答案 3 :(得分:1)

int res = (int)typeof(MyClass).InvokeMember(
                name: "GetMonthsDateDiff", 
                invokeAttr: BindingFlags.NonPublic |
                            BindingFlags.Static |
                            BindingFlags.InvokeMethod,
                binder: null, 
                target: null, 
                args: args);

答案 4 :(得分:0)

MyClass myClass = new MyClass();
PrivateObject testObj = new PrivateObject(myClass);
DateTime fromDate = new DateTime(2015, 1, 1);
DateTime toDate = new DateTime(2015, 3, 17);
object[] args = new object[2] { fromDate, toDate };

//The extra flags
 BindingFlags flags = BindingFlags.Static| BindingFlags.NonPublic
int res = (int)testObj.Invoke("GetMonthsDateDiff",flags, args);