Nous mettons tous nos tests unitaires dans leurs propres projets. Nous constatons que nous devons rendre certaines classes publiques au lieu de internes uniquement pour les tests unitaires. Existe-t-il de toute façon pour éviter d'avoir à le faire. Quelles sont les implications de la mémoire en rendant les classes publiques au lieu d'être scellées?
Si vous utilisez .NET, l'attribut InternalsVisibleTo Assembly vous permet de créer des assemblys "amis". Ce sont des assemblys spécifiques fortement nommés qui sont autorisés à accéder aux classes internes et aux membres de l'autre assembly.
Remarque, cela doit être utilisé avec discrétion car il couple étroitement les assemblages impliqués. Une utilisation courante pour InternalsVisibleTo est pour les projets de tests unitaires. Ce n'est probablement pas un bon choix pour une utilisation dans vos assemblys d'application réels, pour la raison indiquée ci-dessus.
Exemple:
[Assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{
S'il s'agit d'une classe interne, elle ne doit pas être utilisée de manière isolée. Par conséquent, vous ne devriez pas vraiment le tester à part tester une autre classe qui utilise cet objet en interne.
Tout comme vous ne devez pas tester les membres privés d'une classe, vous ne devez pas tester les classes internes d'une DLL. Ces classes sont des détails d'implémentation de certaines classes accessibles au public et doivent donc être bien exercées par le biais d'autres tests unitaires.
L'idée est que vous souhaitez uniquement tester le comportement d'une classe, car si vous testez les détails de l'implémentation interne, vos tests seront fragiles. Vous devriez pouvoir modifier les détails d'implémentation de n'importe quelle classe sans casser tous vos tests.
Si vous trouvez que vous avez vraiment besoin de tester cette classe, vous voudrez peut-être réexaminer pourquoi cette classe est interne en premier lieu.
à des fins de documentation
vous pouvez également instancier la classe interne en utilisant Type.GetType
méthode
exemple
//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*/ });
pour le type générique, il existe différents processus comme ci-dessous:
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*/});