2015-02-16 13 views
6

mam tej klasy:testu prywatnego metoda statyczna rzuca MissingMethodException

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

Teraz jestem wykonawczych testów jednostkowych dla niego. Ponieważ metoda jest prywatny, mam następujący kod:

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 

Wyjątek typu „System.MissingMethodException” wystąpił w pliku mscorlib.dll ale nie było obsługiwane w kodzie użytkownika Informacje dodatkowe: próbował uzyskać dostęp brakujący członek.

Co robię źle? Metoda istnieje ..

Odpowiedz

15

Jest to metoda statyczna, więc użyj PrivateType zamiast PrivatObject, aby uzyskać do niej dostęp.

Zobacz PrivateType.

+8

i 'InvokeStatic()' 'zamiast Invoke()' to nazwać. –

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

Metoda Invoke jest tą, której nie można znaleźć. Klasa Object nie ma metody Invoke. Myślę, że możesz próbować użyć this Invoke, która jest częścią System.Reflection.

Można go używać tak,

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

Jednak, nie należy próbować przetestować metodę private; jest zbyt specyficzny i może ulec zmianie. Powinieneś zamiast tego zrobić public z klasy DateCalculator, która jest prywatna w MyClass, lub może, czyniąc ją internal, więc możesz używać tylko wewnątrz swojego zespołu.

4

skorzystać z poniższego kodu z 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) 
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); 
Powiązane problemy