Frage

Wir setzen alle unsere Unit-Tests in eigenen Projekten. Wir finden, dass wir bestimmte Klassen Öffentlichkeit statt internen nur für die Unit-Tests machen. Gibt es trotzdem, um zu vermeiden, dies zu tun. Was sind die Speicher Implikation von Klassen Öffentlichkeit statt versiegelt zu machen?

War es hilfreich?

Lösung

Wenn Sie .NET verwenden, die InternalsVisibleTo Assemblierung-Attribut ermöglicht es Ihnen, „Freund“ Baugruppen zu erstellen. Dies sind spezifische stark benannte Baugruppen, die erlaubt den Zugriff auf interne Klassen und die Mitglieder der anderen Baugruppe.

Beachten Sie, dies sollte die beteiligten Baugruppen mit Diskretion, da sie eng Paare verwendet werden. Eine übliche Verwendung für InternalsVisibleTo ist für Einheitentests Projekte. Es ist wahrscheinlich keine gute Wahl für den Einsatz in Ihrem aktuellen Anwendung Baugruppen, für den oben genannten Grund.

Beispiel:

[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{

Andere Tipps

Wenn es eine interne Klasse ist, dann muss es nicht isoliert verwendet werden, zu werden. Deshalb sollten Sie nicht wirklich außer testen eine andere Klasse zu testen, die intern Verwendung dieses Objekts macht.

So wie Sie nicht private Mitglieder einer Klasse testen sollten, sollten Sie nicht auf interne Klassen einer DLL testen werden. Diese Klassen sind Implementierungsdetails von einigen öffentlich zugänglichen Klasse und sollten daher auch durch andere Unit-Tests ausgeübt werden.

Die Idee ist, dass Sie nur das Verhalten einer Klasse testen wollen, denn wenn Sie Details interne Implementierung testen dann Ihre Tests spröde sein. Sie sollten die Details der Implementierung einer Klasse zu ändern, ohne zu brechen alle Tests in der Lage sein.

Wenn Sie feststellen, dass Sie wirklich die Klasse testen müssen, dann könnten Sie nochmals zu prüfen wollen, warum diese Klasse in erster Linie intern ist.

für Dokumentationszwecke

Alternativ können Sie interne Klasse instanziiert durch Type.GetType Methode mit

Beispiel

//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*/ });

für generischen Typen gibt es verschiedene Verfahren, wie unten:

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*/});

Klassen sowohl öffentliche und abgedichtet werden können.

Aber tun Sie das nicht.

Sie können ein Werkzeug erstellen über interne Klassen zu reflektieren, und eine neue Klasse emittieren, die alles über Reflexion zugreift. MSTest tut das.

Edit: Ich meine, wenn Sie -Alle- Tests nicht Sachen in Ihrer ursprünglichen Baugruppe enthalten sein sollen; Dies funktioniert auch, wenn die Mitglieder privat sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top