Testing a private static method throws a MissingMethodException

I have this class:

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

Now I am implementing a unit test for it. Since the method is private, I have the 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 processed in the user code Additional information: An attempt was made to access a missing item.

What am I doing wrong? Method exists ..

+6
source share
5 answers

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

See PrivateType .

+16
source

Use the code below 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) 
+4
source

The Invoke method is one that cannot be found. The Object class does not have an Invoke method. I think you can 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 try to test the private method; it is too specific and can be changed. You should instead make the public of the DateCalculator class, which is private in MyClass or perhaps makes it internal , so you can only use it inside your assembly.

+3
source
 int res = (int)typeof(MyClass).InvokeMember( name: "GetMonthsDateDiff", invokeAttr: BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, binder: null, target: null, args: args); 
+1
source
 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); 
0
source

Source: https://habr.com/ru/post/982570/


All Articles