it-swarm.com.de

Code intern, aber für Komponententests aus anderen Projekten verfügbar machen

Wir testen alle unsere Einheiten in eigenen Projekten. Wir stellen fest, dass wir nur für die Komponententests bestimmte Klassen öffentlich machen müssen, anstatt interne. Gibt es sowieso zu vermeiden, dies zu tun. Welche Auswirkungen hat die Veröffentlichung von Klassen anstelle von versiegelten Klassen auf das Gedächtnis?

119
leora

Wenn Sie .NET verwenden, können Sie mit dem Attribut InternalsVisibleTo Assembly "Friend" -Baugruppen erstellen. Hierbei handelt es sich um bestimmte Assemblys mit starkem Namen, die auf interne Klassen und Mitglieder der anderen Assembly zugreifen dürfen.

Beachten Sie, dass dies mit Diskretion verwendet werden sollte, da es die beteiligten Baugruppen eng miteinander verbindet. InternalsVisibleTo wird häufig für Unit-Test-Projekte verwendet. Aus dem oben genannten Grund ist es wahrscheinlich keine gute Wahl für die Verwendung in Ihren tatsächlichen Anwendungsassemblys.

Beispiel:

[Assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{
188
Ash

Wenn es sich um eine interne Klasse handelt, darf sie nicht isoliert verwendet werden. Aus diesem Grund sollten Sie es nicht wirklich testen, es sei denn, Sie testen eine andere Klasse, die dieses Objekt intern verwendet.

So wie Sie keine privaten Member einer Klasse testen sollten, sollten Sie auch keine internen Klassen einer DLL testen. Diese Klassen sind Implementierungsdetails einiger öffentlich zugänglicher Klassen und sollten daher durch andere Komponententests gut trainiert werden.

Die Idee ist, dass Sie nur das Verhalten einer Klasse testen möchten, denn wenn Sie interne Implementierungsdetails testen, werden Ihre Tests spröde. Sie sollten in der Lage sein, die Implementierungsdetails einer Klasse zu ändern, ohne alle Ihre Tests zu unterbrechen.

Wenn Sie feststellen, dass Sie diese Klasse wirklich testen müssen, sollten Sie überprüfen, warum diese Klasse überhaupt intern ist.

6
Josh

zu Dokumentationszwecken

alternativ können Sie die interne Klasse mit der Methode Type.GetType instanziieren

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 generische typen gibt es verschiedene prozesse wie folgt:

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