2010-09-06 10 views
10

Czytam jedną książkę o JUnit teraz i pisarz zaleca usuwanie zasobów w metodzie tearDown. Czemu? Czy to nie jest praca GC? Czy może poważnie zaszkodzić?JUnit - czy należy przypisać wartość null do zasobów w tearDown, które zostały utworzone w setUp?

Pozwala myśleć o przykład takiego:

public class SomeTest extends TestCase { 
    Vector vector; 
    List<Object> list; 

    protected void setUp() { 
    vector = new Vector(); 
    list = new ArrayList<Object>(); 
    } 

    // messing with resources 
    // adding, deleting, testing whatever 

    protected void tearDown() { 
    vector = null; 
    list = null; 
    } 
} 

Co o tym sądzisz? Czy ten kod w tearDown jest niezbędny?

Odpowiedz

9

Tak, to naprawdę może być konieczne.

Widzisz, JUnit rzeczywiście utworzyć osobną instancję klasy Test dla każdej metody testowej i testy biegacz Junit3 (nie tak z JUnit4) zachowa te instancje dookoła, aż cały zestaw testowy zakończył.

W związku z tym, jeśli twoja klasa testowa (JUnit3) ma pola, które zajmują dużo pamięci, możesz łatwo uruchomić przestrzeń sterty, gdy masz dużą liczbę metod testowania. Oczywiście, jeśli te zbiory w przykładowym kodzie zawierają tylko garść krótkich łańcuchów, nie ma to znaczenia.

+0

Interesujące, nie wiedziałem, że każda metoda używa własnej instancji Test: O Thanx ... – Xorty

+1

To samo dotyczy JUnit 4. –

+0

Ok ... wszyscy za pomoc, ale to jest dla mnie najciekawsza odpowiedź, więc zaznaczam to zaakceptowane. – Xorty

3

Zależy od tego, co uważasz za źródło. Podczas gdy przestrzeń sterty jest zasobem, prawdopodobnie możesz uniknąć czyszczenia GC po tobie (YMMV).

Rzeczy, które mogą powodować problemy, są takie jak połączenia z bazami danych/otwarte pliki i strumienie itp., Które powinny być zawsze zamykane po użyciu, aby zapobiec pojawieniu się złych w długim kodzie.

Kiedyś zdarzyło się, że test integracyjny dla kodu hibernacji nie został poprawnie oczyszczony i spowodował kilka naprawdę dziwnych błędów. Wiele czasu zajęło mi znalezienie i rozgniewanie mnie tak bardzo, że już nigdy więcej nie popełnię tego błędu.

+0

Widzę, że to jest to. Autor powinien był napisać tak :) Więc na przykład napisałem powyżej, to jest bezużyteczne, prawda? – Xorty

+0

Tak :) Twój przypadek testowy powinien być w porządku. Zwykle staram się unikać przypadków @Before i @After - po prostu zrób to w razie potrzeby. – gpampara

+0

Jeśli SomeTest był częścią bardzo dużego TestSuite z wieloma TestCase i somes TestCases w tym TestSuite tworzy obiekty w setUp(), które zajmują dużo pamięci i nie usuwają odniesień w tearDown(), to tak, możesz wyczerpuje pamięć podczas uruchamiania pakietu. Zauważ, że odpowiedź jest inna dla testów stylu JUnit 4.x. – NamshubWriter

1

Testy i zestawy testów JUnit 4.x obsługują to inaczej niż zestawy testów JUnit 3.x.

TL; DR: ty należy ustawić pola null w testach JUnit3 stylu ale nie trzeba w testach JUnit4 stylu.

Z testów JUnit 3.x stylu, wykorzystując TestSuite zawiera odnośniki do innych Test przedmiotów (które mogą być TestCase przedmioty lub inne TestSuite obiektów). Jeśli utworzysz pakiet z wieloma testami, wtedy będą ciężkie odwołania do wszystkich obiektów z liścia TestCase dla całego przebiegu najbardziej zewnętrznego pakietu. Jeśli niektóre z obiektów TestCase przydzielają obiekty w rozmiarze setUp(), które zajmują dużo pamięci, a odwołania do tych obiektów są przechowywane w polach, które nie są ustawione na null w tearDown(), może to oznaczać problem z pamięcią.

Innymi słowy, w przypadku testów stylu JUnit 3.x specyfikacja testów do wykonania odnosi się do rzeczywistych obiektów TestCase. Wszelkie obiekty osiągalne z obiektu TestCase będą przechowywane w pamięci podczas testu.

Dla testów stylu JUnit 4.x specyfikacja testów do uruchomienia korzysta z obiektów Description. Obiekt Description jest obiektem wartościowym, który określa, co należy uruchomić, ale nie sposób jego uruchomienia. Testy są przeprowadzane przez obiekt Runner, który pobiera Description testu lub pakietu i określa, w jaki sposób wykonać test.Nawet powiadomienie o statusie testu słuchaczowi testowemu korzysta z obiektów Description.

Domyślna prowadnica dla przypadków testowych JUnit4, JUnit4, zachowuje odniesienie do obiektu testowego tylko na czas trwania tego testu. Jeśli używasz niestandardowego biegacza (za pomocą adnotacji @RunWith), ten biegacz może lub nie może zachować odniesienia do testów wokół przez dłuższy czas.

Być może zastanawiasz się, co się stanie, jeśli włączysz klasę testową w stylu JUnit3 w stylu JUnit4 Suite? JUnit4 zadzwoni pod numer new TestSuite(Class), który utworzy osobną instancję TestCase dla każdej metody testowej. Biegacz będzie utrzymywał odniesienie do TestSuite przez cały czas trwania testu.

Krótko mówiąc, jeśli piszesz testy w stylu JUnit4, nie przejmuj się ustawianiem pól testowych na null w oderwaniu (oczywiście wolne zasoby). Jeśli piszesz testy w stylu JUnit3, które przydzielają duże obiekty w setUp() i przechowujesz te obiekty w polach TestCase, rozważ ustawienie pól na null.

Powiązane problemy