Testy jednostkowe.

0

Witam.

Mam programik, który losuje sobie dwie liczby, jedną z podanego zakresu, a drugą <2,15>. W programie chodzi o to, żeby zamienił wylosowaną liczbę w systemie dziesiętnym na jej odpowiednik w innym wylosowanym systemie. Dodatkowo mam do tego napisać testy w JUnit 3 i 4. Niestety nie bardzo rozumiem to testowanie, gównie chodzi o składnie. Pokarzę na przykładzie.

Mam metodę w klasie Liczba, która losuję liczbę w systemie dziesiętnym.

	public static int liczba(int zakres){
		Random generator = new Random();
		int liczba = generator.nextInt(zakres);
		return liczba;
	}

Teraz chcę dla niej napisać metodę testową czy aby na pewno wygenerowana liczba nie przekroczyła zakresu. (Tylko na ten test wpadłem może da się coś innego przetestować?)

	@Test
	public void testLiczba() {
		int zakres=200;
		Liczba l = new Liczba();
		int liczba = l.liczba(zakres);
		assertEquals("Coś jest nie tak", liczba<200);
	}

Oczywiście moja metoda nie przechodzi testu. Proszę o podpowiedz co robię źle.

0

o_O

assertTrue(liczba<200);

assert equals sprawdza czy oba podane argumenty są zgodne...

0

Testy jednostkowe nie są stworzone do testowania rzeczy losowych, test jednostkowy ma zagwarantować powtarzalność, test którego wynik jest różny każdym wywołaniu jest zbędny bo niczego nie testuje.

1

Po pierwsze ten kod powinien być przetestowany tylko pod kątem odpowiedniego przepływu. Klasa Random jest klasą z API i nie powinieneś zastanawiać się czy działa dobrze (czy nextInt(zakres) rzeczywiście zwróci liczbę nie większą niż zakres). W tym celu należy oczywiście sprawdzić czy metoda liczba wywołuje metodę nextInt(zakres). I tu wchodzimy na pole minowe...

  1. Olewamy test zakładając, że nasza metoda to tylko wrapper i działa jak należy - złe podejście.
  2. Piszemy testy tylko dla przypadków granicznych i nieprawidłowych - co będzie jak zakres przyjmie wartości ujemne bądź 0?
  3. Używamy PowerMock i jego featurów do mockowania(udawania/tworzenia dublerów) klas tworzonych przez SUT (ang. system under test) za pomocą new. Tu trzeba by zastąpić Random i zweryfikować czy została wywołana odpowiednia metoda z odpowiednim parametrem.
  4. Modyfikujemy kod tak by nie miał twardej zależności do Random.
class MojGenerator{

        private IRandomWrapper generator;
        
        public MojGenerator(IRandomWrapper generator){
             this.generator= generator;
        }        

        public static int liczba(int zakres){
                int liczba = generator.nextInt(zakres);
                return liczba;
        }

}

interfejs IRandom opakowuje różne generatory i unifikuje ich interfejsy. Można wtedy zrobić mock(IRandom.class) i podstawić taki mock do naszego generatora. Można też zrezygnować z tego interfejsu, a konstruktor przepisać do postaci:

public MojGenerator(Random generator){
    this.generator= generator;
}

wtedy wstrzeliwujemy mock(Random.class) i możemy przetestować flow.

1 użytkowników online, w tym zalogowanych: 0, gości: 1