2015-02-16 15 views
6

Ich habe diese Klasse:Test-private statische Methode wirft Missing

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

Jetzt bin der Umsetzung I Unit-Test für sie. Da das Verfahren ist privat, ich folgenden Code haben:

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 

Eine Ausnahme vom Typ ‚System.MissingMethodException‘ in mscorlib.dll aufgetreten, wurde aber in Benutzercode Zusätzliche Informationen nicht behandelt: Versuchte einen fehlenden Zugriff auf Mitglied.

Was mache ich falsch? Die Methode existiert ..

Antwort

15

Es ist eine statische Methode, also verwenden Sie PrivateType anstelle von PrivatObject, um darauf zuzugreifen.

Siehe PrivateType.

+8

Und 'invokestatic()' statt 'Invoke()' es zu nennen. –

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

Die Invoke Methode ist diejenige, die nicht gefunden werden kann. Die Klasse Object hat keine Invoke-Methode. Ich denke, Sie könnten versuchen, this Invoke zu verwenden, der Teil von System.Reflection ist.

Sie es so verwenden können,

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

jedoch, sollten Sie keine private Methode zu testen versuchen; es ist viel zu spezifisch und kann sich ändern. Sie sollten es stattdessen public einer DateCalculator Klasse machen, die in MyClass privat ist, oder vielleicht, es internal machend, also können Sie nur innerhalb Ihrer Versammlung verwenden.

4

Verwenden Sie die folgenden Code mit Privaten

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