YAKOVM
YAKOVM

Reputation: 10153

Test private static method throws MissingMethodException

I have this class:

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

Now I am implementing unit test for it. Since the method is private, I have following code:

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

An exception of type 'System.MissingMethodException' occurred in mscorlib.dll but was not handled in user code Additional information: Attempted to access a missing member.

What Am I doing wrong? The method exists..

Upvotes: 14

Views: 6271

Answers (5)

Tomas Hesse
Tomas Hesse

Reputation: 395

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); 

Upvotes: 1

dayanand
dayanand

Reputation: 111

Use below code with 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)

Upvotes: 11

EZI
EZI

Reputation: 15364

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

Upvotes: 1

rae1
rae1

Reputation: 6144

The Invoke method is the one that cannot be found. The Object class does not have an Invoke method. I think you might be trying to use this Invoke, which is part of System.Reflection.

You can use it like this,

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);

However, you should not be trying to test a private method; it is much too specific and subject to change. You should instead make it public of a DateCalculator class which is private in MyClass, or perhaps, making it internal, so you can only use inside your assembly.

Upvotes: 4

Brian Rasmussen
Brian Rasmussen

Reputation: 116401

It is a static method, so use PrivateType instead of PrivatObject to access it.

See PrivateType.

Upvotes: 27

Related Questions