You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Next »

Enhetstesting er testing av de minste enhetene i et program, i praksis enkeltklasser og deres metoder. Ved testing av metoder, vil en typisk rigge opp en eller flere instans, kalle metodene med ulike argumenter og sammenligne returverdiene med fasiten. Dette vil imidlertid ikke teste et annet viktig aspekt ved metoder, nemlig når og hvilke unntak som utløses, f.eks. når argumenter er ugyldige. Testing av dette er ikke like rett frem som ved testing av returverdier, og derfor trenger en å kjenne ulike teknikker for å teste unntak.

Heldigvis finnes det en egen JUnit-metode for å test unntak, nemlig assertThrows. Den brukes som følger:

@Test
public void testCount() {
	counter.count();
	counter.count();
	assertThrows(IllegalStateException.class, () -> {
		counter.count();
	});
}


Når man tester unntak, så vil man typisk ønske å sjekke om kontrollflyten fortsetter som vanlig eller havner i en bestemt catch-del. For å angi at en bestemt kontrollflyten ikke er som forventet, dvs. "hit skulle man ikke kommet", kaller man fail()-metoden, som rett og slett gir feilmelding umiddelbart, omtrent som om en brukte assertTrue(true). Anta f.eks. at konstruktøren i Counter-klassen fra Enhetstesting med JUnit skal utløse en IllegalArgumentException, dersom end-verdien er mindre enn start-verdien. Da må en teste begge tilfeller, både når en forventer unntak av denne typen og når en ikke forventer det, gjerne i hver sin test-metode:

public void testCounterWithoutException() {
   try {
      // prøve to tilfeller, både mindre enn og lik
      new Counter(1, 2);
      new Counter(1, 1);
      // skal komme hit
   } catch (Exception e) (
      // forventer ingen unntak, så skal ikke komme hit
      fail();
   }
}

public void testCounterException() {
   try {
      new Counter(1, 0);
      // forventer unntak, så skal ikke komme hit
      fail();
   } catch (IllegalArgumentException iae) (
      // forventer unntak av denne typen, så skal komme hit
   } catch (Exception e) (
      // forventer ikke andre unntak, så skal ikke komme hit
      fail();
   }
}

En trenger forsåvidt ikke catch-grenen for Exception med fail() i, fordi den likevel vil bli fanget opp av test-systemet, men det er greit å ha den med fordi den gjør test-koden tydeligere på hva slags unntak som forventes og ikke.

Det er ett tilfelle koden over ikke dekker, nemlig når det kreves et unntak av en bestemt klasse og ikke en subklasse. Dersom Counter-konstruktøren utløser et unntak av typen NumberFormatException, vil dette blir akseptert av testkoden over, men dette unntaket passer jo egentlig ikke. Kravet til konstruktøren bør være at unntaket er av den bestemte klassen IllegalArgumentException (og ikke en subklasse) og dette kan en teste med følgende kode:

public void testCounterException() {
   try {
      new Counter(1, 0);
      // forventer unntak, så skal ikke komme hit
      fail();
   } catch (Exception e) (
      // forventer unntak, men bare av en bestemt klasser
      assertTrue(e.getClass().equals(IllegalArgumentException.class));
   }
}

Her fanger en altså opp alle unntak og sjekker at typen til unntaksinstansen, som returneres med e.getClass(), er den spesifikke klassen IllegalArgumentException.


Sider om Enhetstesting med JUnit:

  • No labels