2009-03-15 13 views
5

Mentre sviluppo codice, desidero spesso testare unitamente alcuni elementi costitutivi di una classe anche se sono normalmente privati. Se i miei test unitari sono all'interno del progetto, posso usare "Friend" per realizzare questo e mantenere comunque le funzioni private per l'uso normale. Ma preferirei spostare i miei test NUnit nei loro progetti separati. Come ottengo l'effetto che sto cercando?Come si esegue il test unitario delle funzioni private da un progetto separato in VB .NET?

risposta

11

Non si può (facilmente) prova privati ​​ metodi da un progetto diverso, ma è abbastanza comune per testare interne metodi (Friend in VB) da un progetto di test utilizzando InternalsVisibleToAttribute. Ciò rende i membri di Friend accessibili a un altro assembly.

Apparentemente questo era nuovo in VB 9 anche se era disponibile in C# 2 ... non del tutto sicuro del perché, ma this blog post from Bart de Smet fornisce un rapido esempio.

Si noti che se l'assembly di produzione è firmato, sarà necessario firmare anche l'assembly di test e sarà necessario specificare la chiave pubblica negli argomenti InternalsVisibleToAttribute. Vedi this Stack Overflow answer per maggiori dettagli.

+2

Quanto al perché era nuovo in VB9, era un costo/vantaggioso commercio. VB ha un modo molto diverso di risolvere i nomi che C# e InternalsVisibleTo complica molto la ricerca dei nomi. Era troppo costoso per VB8 e quindi è sceso a VB9. In realtà stiamo apportando ulteriori modifiche alla risoluzione dei nomi con (cont) – JaredPar

+0

(cont) conto per questo in VB10. – JaredPar

+0

grazie per questa risposta –

3

È possibile utilizzare Reflection per richiamare i metodi privati. Ci sono un sacco di campioni là fuori per fare questo.

+0

E questo è quello che mi ha aiutato di più: http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx – demoncodemonkey

1

Da una rapida ricerca google: http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx

I principi fondamentali: (questo viene incollato dal sito del progetto di codice linkato sopra)

 public static object RunStaticMethod(System.Type t, string strMethod, 
    object [] objParams) 
    { 
     BindingFlags eFlags = 
     BindingFlags.Static | BindingFlags.Public | 
     BindingFlags.NonPublic; 
     return RunMethod(t, strMethod, 
     null, aobjParams, eFlags); 
    } //end of method 

    public static object RunInstanceMethod(System.Type t, string strMethod, 
    object objInstance, object [] aobjParams) 
    { 
     BindingFlags eFlags = BindingFlags.Instance | BindingFlags.Public | 
     BindingFlags.NonPublic; 
     return RunMethod(t, strMethod, 
     objInstance, aobjParams, eFlags); 
    } //end of method 

    private static object RunMethod(System.Type t, string 
    strMethod, object objInstance, object [] aobjParams, BindingFlags eFlags) 
    { 
     MethodInfo m; 
     try 
     { 
      m = t.GetMethod(strMethod, eFlags); 
      if (m == null) 
      { 
       throw new ArgumentException("There is no method '" + 
        strMethod + "' for type '" + t.ToString() + "'."); 
      } 

      object objRet = m.Invoke(objInstance, aobjParams); 
      return objRet; 
     } 
     catch 
     { 
      throw; 
     } 
    } //end of method 
Problemi correlati