Jak zezwolić zestawowi (testowi jednostkowemu) na dostęp do wewnętrznych właściwości innego zestawu?

80

Chciałbym, aby mój zespół Core nie ujawniał określonej klasy i nadal chciałbym móc go przetestować. Jak mogę to zrobić ?

Tomas Pajonk
źródło

Odpowiedzi:

107

Atrybut InternalsVisibleTo na ratunek!

Poprostu dodaj:

[assembly:InternalsVisibleToAttribute("UnitTestAssemblyName")]

do pliku klas podstawowych AssemblyInfo.cs

Zobacz zestawy znajomych (przewodnik programowania C #), aby uzyskać najlepsze rozwiązania.

aku
źródło
3
Po prostu zrobiłem to pomyślnie z silnie nazwanym zespołem, postępując zgodnie ze wskazówkami, do których prowadzi aku. Miałem jednak jeden problem. Po skonfigurowaniu wszystkiego musiałem ponownie uruchomić Visual Studio, aby Intellisense działało. Skompilowałby się przed ponownym uruchomieniem, ale zawsze pokazywałby czerwone linie.
Eric Schoonover,
20

Z InternalsVisible, jeśli twoje zestawy są silnie nazwane, musisz określić klucz publiczny (uwaga: pełny klucz, a nie token klucza publicznego) na przykład ...

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("BoardEx_BusinessObjects.Tests, 
  PublicKey=0024000004800000940000000602000000240000525341310004000001000100fb3a2d8 etc etc")]

a następująca sztuczka jest naprawdę przydatna do uzyskania klucza publicznego bez uciekania się do wiersza cmd ...

http://www.andrewconnell.com/blog/archive/2006/09/15/4587.aspx

Simon Keep
źródło
9

Umieściłem moje testy jednostkowe w tym samym zestawie, co testowany kod. Ma to dla mnie sens, ponieważ myślę o „przetestowaniu siebie” jako o cechach zajęć, razem z takimi rzeczami jak „zainicjuj siebie” i „opisz siebie”.

Słyszałem pewne zastrzeżenia do tego podejścia, ale niewiele z nich było przekonujących.

To szkodzi wydajności Bah, mówię! Nie optymalizuj bez twardych danych! Być może, jeśli planujesz pobieranie zestawów za pomocą wolnych łączy, warto byłoby zminimalizować rozmiar zespołu.

To zagrożenie bezpieczeństwa . Tylko jeśli masz tajemnice w swoich testach. Nie rób tego.

Twoja sytuacja różni się od mojej, więc może będzie to miało dla ciebie sens, a może nie. Musisz sam to rozgryźć.

Poza tym: w C # próbowałem kiedyś umieścić testy jednostkowe w klasie o nazwie „Testy”, która była zagnieżdżona w testowanej klasie. To sprawiło, że prawidłowa organizacja rzeczy była oczywista. Uniknięto również powielania nazw, które ma miejsce, gdy testy dla klasy „Foo” znajdują się w klasie o nazwie „FooTests”. Jednak frameworki testów jednostkowych, do których miałem dostęp, odmawiały akceptacji testów, które nie zostały oznaczone jako „publiczne”. Oznacza to, że testowana klasa nie może być „prywatna”. Nie przychodzi mi do głowy żaden dobry powód, by wymagać, aby testy były „publiczne”, ponieważ nikt tak naprawdę nie nazywa ich metodami publicznymi - wszystko odbywa się poprzez refleksję. Jeśli kiedykolwiek napiszesz framework do testów jednostkowych dla .Net, rozważ dopuszczenie testów niepublicznych, ze względu na mnie!

Jay Bazuzi
źródło
5
Ciekawe podejście. I całkowicie zgadzam się z tym, że testy są publiczne. Głupi wymóg, IMO.
Kilhoffer
@Kilhoffer: Narzekam na to od lat i jesteś pierwszą osobą, która naprawdę się ze mną zgadza. Dzięki!
Jay Bazuzi
6
Jeśli używasz [Conditional("DEBUG")]na klasach testowych, nie powinny one znajdować się w montażu produkcyjnym i nie szkodzić wydajności.
xmedeko
3

Sugerowałbym unikanie takich kłopotów ... jeśli naprawdę chcesz przetestować swoje "wewnętrzne" klasy, po prostu ukryj je w przestrzeni nazw, której użyje tylko twój wewnętrzny kod. Jeśli nie piszesz frameworka w skali .NET, tak naprawdę nie potrzebujesz takiego poziomu ukrywania.

Joel Martinez
źródło
Zamierzałem skomentować dokładnie to, co powiedziałeś, kiedy zauważyłem twój komentarz na dole. +1! :)
Bjorn Reppen
2

Możesz użyć odbicia (tak jak robią to elementy testu MS) lub możesz zadeklarować zestaw testów jednostkowych jako przyjaciel zestawu podstawowego.

Inną opcją jest umieszczenie testów jednostkowych w tym samym zestawie.

Dan Blair
źródło