2009-11-06 19 views
16

Mam klasę o nazwie "Sesja", która ujawnia kilka publicznych metod. Chciałbym je przetestować, jednak w produkcji muszę kontrolować instancję obiektów "Sesji", więc przekazać konstrukcję do klasy SessionManager i uczynić konstruktor Sesji wewnętrznym.Jednostka Testowanie klasy z wewnętrznym konstruktorem

Idealnie chciałbym przetestować klasę Session w izolacji od SessionManager, która tworzy/im, aby udowodnić, że publiczne interfejsy odsłonięte przez sesję działają zgodnie z oczekiwaniami - ale nie może utworzyć sesji z testu bez użycia SessionManager sprawia, że ​​moje testy są bardziej skomplikowane/mniej użyteczne niż muszą być.

Jaki jest najlepszy sposób, aby sobie z tym poradzić?

Cheers,

Lenny.

+0

plese wyjaśnić: jest to jest chroniony ___lub___ wewnętrzny konstruktor? –

Odpowiedz

42

Nic uniemożliwia testów wewnętrznych Wystarczy uczynić wewnętrzne o kodzie widoczne dla zestawu testowego, za pomocą atrybutu InternalsVisibleTo:.. w AssemblyInfo, dodać

[assembly:InternalsVisibleTo("TestSuiteAssembly")] 
+0

Wydaje się, że jest to najłatwiejszy sposób na zrobienie tego, więc myślę, że zacznę z tym. Dzięki. –

+1

Odpowiedź nie jest kompletna - należy złożyć podpisy, aby działało. – Santhos

+0

@Santhos nie bardzo ... –

2

Można po prostu sprawić, że klasa testów jednostkowych dziedziczy po sesji (zakładając, że struktura testowa nie wymaga dziedziczenia z określonej klasy). Na przykład, z NUnit:

[TestFixture] 
public class SessionTest : Session 
{ 
    public SessionTest() 
     : base() // call protected constructor 
    { 
    } 

    [Test] 
    public void TestSomething() 
    { 
    } 

} 
+1

OP powiedział, że ctor jest wewnętrzny, a nie chroniony. –

+0

@Rex - tytuł pytania mówi "chroniony", podczas gdy samo pytanie mówi "wewnętrzny". –

1

Chcesz korzystać z produktu jak TypeMock, który pozwoli Ci stworzyć wyśmiewany (sfałszowane) instancje klas, na przykład:

var myInstance = Isolate.Fake.Instance<Session>(); 
// mock behavior here 
// do assertions here 

Można tworzyć instancje klas abstrakcyjnych również z TypeMock, dla rekordu.

+3

kpiny z tej samej klasy, którą chciałbyś przetestować, nie mają dla mnie większego sensu ... czy nie testowałbyś wtedy egzaminu, a nie klasy? – Svish

+0

@Svish, masz rację, że sfałszowane zachowanie nie jest użyteczne, ale może również utworzyć prawdziwą instancję i rozwiązać problem z dostępnością: Isolate.Fake.Instance (Members.CallOriginal). W ten sposób masz rzeczywistą instancję klasy, której konstruktor jest niedostępny. Nota prawna - pracuję w firmie Typemock. – Elisha

2

Alternatywnie, jako rozwiązanie tymczasowe, można po prostu utworzyć sesję testową dziedziczącą po sesji i udostępniającą publiczny konstruktor. Wewnątrz twojego testu jednostkowego możesz użyć TestSession, która w zasadzie działa tak samo jak oryginalny obiekt Sesji.

public class TestSession : Session 
{ 

    public TestSession() : base() 
    { 

    } 

} 
1

Chciałbym zakwestionować wartość tworzenia wewnętrznego konstruktora klasy sesji.

Generalnie oznacza to, że próbujesz uniemożliwić innym programistom korzystanie z klasy. Może lepiej byłoby przekazać, w jaki sposób działa ta konkretna część aplikacji i dlaczego chcesz uzyskać dostęp do sesji tylko przez menedżera sesji?

+0

Widziałem, jak wiele zdziałałem z modelem fabrycznym, w którym możesz chcieć wymusić, że klasa jest tworzona lub niszczona tylko w jednym miejscu, ale inni ludzie mogą do niej odwoływać się i używać jej. –

+0

Widziałem to również dobrze :) Po prostu nie widzę, w jaki sposób dodaje żadnej wartości. Po prostu powoduje problemy, gdy chcesz rozszerzyć lub przetestować - tak jak teraz doświadcza Leonard. MS jest jednym z najgorszych przestępców w tym względzie, istnieje mnóstwo klas wewnętrznych, które byłyby przydatne do użycia czasami, ale po prostu nie możemy uzyskać do nich dostępu! Frustrujący! –

+5

Jako ktoś, kto był kiedyś konsumentem API, i był bardzo sfrustrowany, jakbyś zastanawiał się, dlaczego MS sprawia, że ​​tak wiele rzeczy wewnętrznych, chronionych, itp. Teraz robię głównie rozwój API i moje rzeczy są konsumowane przez innych programistów. Wydaje mi się, że spędzam dużo czasu na sprzątaniu cudzych wiadomości, ponieważ wpadają w kłopoty, używając rzeczy, które powinienem zrobić wewnętrznie. Czasem po prostu nie można oczekiwać, że będziemy w stanie komunikować "właściwe" użycie każdego kodu, który piszemy. –

0

Jeśli możesz wyjść z konstruktorem "chronionym wewnętrznym", a następnie, zakładając, że twoje testy znajdują się w innym zestawie, możesz dodać atrybut InternalsVisibleTo do swojego "testowanego zespołu". Pozwoliłoby to na wynikach badań, aby zobaczyć wewnętrzne członków do-testowane-montażowych”.

Aktualizacja Z jakiegoś powodu czytałem, że konstruktor został zabezpieczony. To już wewnętrzna tak jesteś w dobrej pozycji do używać tego atrybutu

Powiązane problemy