c# - net - mstest



Rendere il codice interno ma disponibile per i test unitari da altri progetti (3)

Abbiamo messo tutti i nostri test unitari nei loro progetti. Scopriamo che dobbiamo rendere pubbliche determinate classi invece che interne solo per i test unitari. C'è comunque da evitare di doverlo fare. Quali sono le implicazioni della memoria rendendo pubbliche le classi invece che sigillate?

https://ffff65535.com


Le lezioni possono essere sia pubbliche che sigillate.

Ma non farlo.

È possibile creare uno strumento per riflettere sulle classi interne ed emettere una nuova classe che accede a tutto tramite la riflessione. MSTest lo fa.

Modifica: Voglio dire, se non si desidera includere, ad esempio, i test nell'assemblaggio originale; questo funziona anche se i membri sono privati.


Se si tratta di una classe interna, non deve essere utilizzata da sola. Quindi non dovresti davvero metterlo alla prova oltre a provare qualche altra classe che fa uso di quell'oggetto internamente.

Proprio come non dovresti testare i membri privati ​​di una classe, non dovresti testare le classi interne di una DLL. Queste classi sono dettagli di implementazione di alcune classi accessibili pubblicamente e pertanto dovrebbero essere ben esercitate attraverso altri test unitari.

L'idea è che vuoi solo testare il comportamento di una classe perché se testi i dettagli di implementazione interna, i tuoi test saranno fragili. Dovresti essere in grado di modificare i dettagli di implementazione di qualsiasi classe senza interrompere tutti i test.

Se trovi che hai davvero bisogno di testare quella classe, allora potresti voler riesaminare perché quella classe è interna in primo luogo.


a scopo di documentazione

in alternativa è possibile creare un'istanza della classe interna utilizzando il metodo Type.GetType

esempio

//IServiceWrapper is public class which is 
//the same assembly with the internal class 
var asm = typeof(IServiceWrapper).Assembly;
//Namespace.ServiceWrapper is internal
var type = asm.GetType("Namespace.ServiceWrapper");
return (IServiceWrapper<T>)Activator
    .CreateInstance(type, new object[1] { /*constructor parameter*/ });

per tipo generico ci sono diversi processi come segue:

var asm = typeof(IServiceWrapper).Assembly;
//note the name Namespace.ServiceWrapper`1
//this is for calling Namespace.ServiceWrapper<>
var type = asm.GetType("Namespace.ServiceWrapper`1");
var genType = type.MakeGenericType(new Type[1] { typeof(T) });
return (IServiceWrapper<T>)Activator
     .CreateInstance(genType, new object[1] { /*constructor parameter*/});




scope