Wszystkie nasze testy jednostkowe umieszczamy we własnych projektach. Odkrywamy, że musimy upublicznić niektóre klasy zamiast wewnętrznych tylko dla testów jednostkowych. Czy w ogóle można tego uniknąć. Jaki jest wpływ pamięci na upublicznianie klas zamiast zapieczętowanych?
c#
unit-testing
scope
leora
źródło
źródło
Odpowiedzi:
Jeśli używasz platformy .NET, atrybut zestawu InternalsVisibleTo umożliwia tworzenie zestawów „zaprzyjaźnionych”. Są to specyficzne silnie nazwane zestawy, które mają dostęp do klas wewnętrznych i elementów członkowskich innego zestawu.
Należy pamiętać, że należy to stosować z rozwagą, ponieważ ściśle łączy zaangażowane zespoły. Typowe zastosowanie InternalsVisibleTo to projekty testów jednostkowych. Prawdopodobnie nie jest to dobry wybór do użycia w rzeczywistych zestawach aplikacji z podanego powyżej powodu.
Przykład:
[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")] namespace NameOfYourNameSpace {
źródło
Jeśli jest to klasa wewnętrzna, nie może być używana w izolacji. Dlatego tak naprawdę nie powinieneś testować tego poza testowaniem innej klasy, która korzysta z tego obiektu wewnętrznie.
Tak jak nie powinieneś testować prywatnych członków klasy, nie powinieneś testować wewnętrznych klas biblioteki DLL. Te klasy są szczegółami implementacji niektórych publicznie dostępnych klas i dlatego powinny być dobrze ćwiczone przez inne testy jednostkowe.
Chodzi o to, że chcesz tylko przetestować zachowanie klasy, ponieważ jeśli przetestujesz szczegóły implementacji wewnętrznej, testy będą kruche. Powinieneś być w stanie zmienić szczegóły implementacji dowolnej klasy bez przerywania wszystkich testów.
Jeśli okaże się, że naprawdę potrzebujesz przetestować tę klasę, możesz w pierwszej kolejności ponownie zbadać, dlaczego ta klasa jest wewnętrzna.
źródło
do celów dokumentacyjnych
alternatywnie możesz utworzyć instancję klasy wewnętrznej przy użyciu
Type.GetType
metody methodprzykład
//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*/ });
dla typu ogólnego istnieją różne procesy, jak poniżej:
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*/});
źródło
Klasy mogą być zarówno publiczne, jak i zapieczętowane.
Ale nie rób tego.
Możesz utworzyć narzędzie do odzwierciedlania klas wewnętrznych i emitować nową klasę, która uzyskuje dostęp do wszystkiego za pośrednictwem odbicia. MSTest to robi.
Edycja: mam na myśli, jeśli nie chcesz włączać -jakie- testowania rzeczy do swojego oryginalnego zestawu; działa to również, jeśli członkowie są prywatni.
źródło
public sealed class
? Jakie masz powody dla tego klejnotu?