14

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..

YAKOVM
  • 9,805
  • 31
  • 116
  • 217

5 Answers5

27

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

See PrivateType.

Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
11

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)
dayanand
  • 111
  • 1
  • 2
4

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.

rae1
  • 6,066
  • 4
  • 27
  • 48
1
int res = (int)typeof(MyClass).InvokeMember(
                name: "GetMonthsDateDiff", 
                invokeAttr: BindingFlags.NonPublic |
                            BindingFlags.Static |
                            BindingFlags.InvokeMethod,
                binder: null, 
                target: null, 
                args: args);
EZI
  • 15,209
  • 2
  • 27
  • 33
1
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); 
Tomas Hesse
  • 385
  • 3
  • 10