JUnit is een standaard framework voor modulair testen in het Java en Kotlin ecosysteem, gebruikt in Android-ontwikkeling voor het controleren van bedrijfslogica op het niveau van geïsoleerde componenten. Het framework biedt een set annotaties, assertie-methoden en een Test Runner voor het automatisch detecteren en uitvoeren van tests. Volgens JUnit.org blijft de bibliotheek de populairste oplossing voor unittesten in het JVM-ecosysteem: meer dan 70% van de Java-projecten gebruikt JUnit in een of andere versie.
Belangrijkste
JUnit is een open-source framework voor het schrijven en uitvoeren van herhaalbare unittesten in Java en Kotlin. Het maakt deel uit van het xUnit-ecosysteem — een familie van frameworks gebaseerd op de architectuur van Kent Beck en Erich Gamma — en is het standaard testinstrument in Android Studio en IntelliJ IDEA.
De belangrijkste taak van JUnit is het isoleren van een klein stukje code (methode, klasse) en het controleren van het gedrag onder gecontroleerde omstandigheden. Tests worden geschreven als gewone Java/Kotlin-klassen met annotaties, en het framework zorgt voor het detecteren van tests, het beheren van hun levenscyclus en het verzamelen van uitvoeringsstatistieken.
De eerste versie van JUnit verscheen in 1997 en veranderde de ontwikkelingsaanpak radicaal door de Test-Driven Development (TDD) praktijken te populariseren. Tegenwoordig is JUnit 5 (Jupiter) de huidige versie, volledig herontworpen met een modulaire architectuur en ondersteuning voor Java 8+ en extensies.
Het mechanisme van JUnit-uitvoering is gebaseerd op het Test Runner-patroon, dat de classpath scant, methoden met de @Test-annotatie vindt, een instantie van de testklasse maakt en de methoden in een bepaalde volgorde uitvoert. De Test Runner beheert de levenscyclus: aanroep BeforeAll → BeforeEach → Test → AfterEach → AfterAll.
JUnit omhult elke testmethode in een afzonderlijke klassinstantie, wat isolatie tussen tests garandeert. Dit betekent dat de velden van de klasse geen toestand behouden tussen verschillende @Test-methoden — elke test begint met een schoon object.
De eenvoudigste test in JUnit ziet eruit als een methode met de @Test-annotatie, waarin de te testen code wordt aangeroepen en het resultaat wordt gecontroleerd via een assertie. Als de assertie faalt — wordt de test als mislukt beschouwd en rapporteert JUnit de fout.
@Test
void additionShouldReturnCorrectSum() {
var calculator = new Calculator();
var result = calculator.add(2, 3);
assertEquals(5, result);
}
De Test Runner vindt automatisch zo’n methode, voert deze uit en rapporteert het resultaat. Als de methode geen uitzondering gooit — is de test geslaagd (green). Als de assertie niet werkt — faalt de test (red).
Annotaties van JUnit bepalen wanneer en hoe de testcode moet worden uitgevoerd. In JUnit 5 bevinden de annotaties zich in het pakket org.junit.jupiter.api en bestrijken ze alle fasen: gegevensvoorbereiding, testuitvoering, opschonen van bronnen.
| Annotatie | Doel | Uitvoering |
|---|---|---|
| @Test | Markeert de testmethode | Één keer per aanroep |
| @BeforeEach | Voorbereiding voor elke test | Voor elke @Test |
| @BeforeAll | Eenmalige initialisatie van de klasse | Één keer voor alle tests |
| @AfterEach | Opschonen na elke test | Na elke @Test |
| @AfterAll | Eenmalige afsluiting van de klasse | Één keer na alle tests |
| @DisplayName | Leesbare naam van de test | Decoratie |
Laten we een volledige testklasse met een correcte levenscyclus bekijken. De methode setUp maakt een nieuwe instantie van Calculator voor elke test, en tearDown maakt bronnen vrij — bijvoorbeeld het sluiten van bestandsdescriptors of databaseverbindingen.
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
void subtractionShouldReturnCorrectResult() {
int result = calculator.subtract(10, 4);
assertEquals(6, result);
}
@AfterEach
void tearDown() {
calculator.reset();
}
}
Asserties zijn statische methoden die het werkelijke resultaat vergelijken met het verwachte en een uitzondering gooien bij een mismatch. JUnit 5 biedt de klasse org.junit.jupiter.api.Assertions met meer dan 25 methoden voor verschillende controlescenario’s — van eenvoudige waardevergelijking tot controle van timeouts en groepsasserties.
De methode assertThrows verdient speciale aandacht — deze maakt het mogelijk om te controleren of de code foutsituaties correct afhandelt — delen door nul, null doorgeven, overschrijden van limieten.
@Test
void divisionByZeroShouldThrowException() {
Calculator calc = new Calculator();
ArithmeticException exception = assertThrows(
ArithmeticException.class,
() -> calc.divide(10, 0)
);
assertEquals("Cannot divide by zero", exception.getMessage());
}
Geparametriseerde tests maken het mogelijk dezelfde testmethode met verschillende argumentensets uit te voeren. In JUnit 5 wordt hiervoor de annotatie @ParameterizedTest gebruikt in combinatie met een gegevensbron — @ValueSource, @CsvSource, @MethodSource of @EnumSource.
Deze aanpak vermindert het dupliceren van code drastisch: in plaats van tien identieke tests voor verschillende waarden wordt één geparametriseerde methode geschreven. Volgens de Google Testing Blog vermindert parametrisering de hoeveelheid testcode met 40–60% zonder verlies van dekking.
De annotatie @CsvSource geeft meerdere regels met een komma als scheidingsteken door aan de test. Elke regel komt overeen met één uitvoering van de test. JUnit converteert de tekenreekswaarden automatisch naar de vereiste typen: int, long, String en andere.
@ParameterizedTest
@CsvSource({
"1, 1, 2",
"2, 3, 5",
"10, 20, 30",
"-1, 1, 0"
})
void additionWithMultipleInputs(int a, int b, int expected) {
assertEquals(expected, a + b);
}
Wanneer de invoergegevens complexer zijn dan eenvoudige getallen of tekenreeksen, wordt @MethodSource gebruikt. Het verwijst naar een statische methode die een Stream van argumenten retourneert — bijvoorbeeld Stream of Arguments of een Stream van User-objecten voor het testen van de DAO-laag.
In Android-ontwikkeling wordt JUnit gebruikt in combinatie met AndroidX Test, dat extensies biedt voor het testen van Activity, Content Provider en andere Android-componenten. JUnit is verantwoordelijk voor unittesten (unit tests) die op de JVM worden uitgevoerd zonder emulator, en AndroidX Test voor instrumentele tests op het apparaat.
Om JUnit 5 in een Android-project aan te sluiten, volstaat het om de afhankelijkheid org.junit.jupiter:junit-jupiter toe te voegen in build.gradle op moduleniveau. De AGP Gradle-plugin ondersteunt het uitvoeren van JUnit 5-tests op de JVM via de standaard Test Runner.
// build.gradle.kts
android {
testOptions {
unitTests.isIncludeAndroidResources = true
}
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.11.0")
testImplementation("androidx.test:core-ktx:1.6.1")
}
In de praktijk wordt JUnit het meest gebruikt voor het testen van ViewModel-klassen en repositories — lagen die geen Android-context of emulator nodig hebben. Zo’n test wordt in milliseconden uitgevoerd en kan honderden keren worden gedraaid zonder tijdverlies.
JUnit 5 (Jupiter) is niet zomaar een nieuwe versie, maar een volledig herontworpen platform verdeeld over drie modules: JUnit Platform (uitvoeren van tests op de JVM), JUnit Jupiter (API voor het schrijven van tests) en JUnit Vintage (achterwaartse compatibiliteit met JUnit 4). Deze modulariteit maakt het mogelijk verschillende Test Engines aan te sluiten — bijvoorbeeld Spek voor Kotlin of TestNG.
| Kenmerk | JUnit 4 | JUnit 5 |
|---|---|---|
| Pakket | org.junit | org.junit.jupiter |
| Basisannotatie | @Test (uit junit.framework) | @Test (uit org.junit.jupiter.api) |
| Before/After | @Before, @After, @BeforeClass | @BeforeEach, @AfterEach, @BeforeAll |
| Parameterized | @RunWith(Parameterized.class) | @ParameterizedTest + @ValueSource |
| Extension | @Rule, @ClassRule | @ExtendWith, flexibeler API |
| Java min | Java 5 | Java 8+ |
Migratie van JUnit 4 naar JUnit 5 vereist niet dat alle tests worden herschreven — het volstaat om JUnit Vintage Engine aan te sluiten en oude tests blijven werken. Nieuwe tests worden aanbevolen in JUnit 5 te schrijven om gebruik te maken van extensies, lambdas in asserties en ingebouwde ondersteuning voor parametrisering.
Veelgestelde vragen
JUnit is een framework voor het schrijven en uitvoeren van tests, en Mockito is een bibliotheek voor het maken van mock-objecten. Ze worden samen gebruikt: JUnit beheert de uitvoering van de test, en Mockito vervangt de afhankelijkheden van de te testen klasse.
Ja, JUnit 5 is volledig compatibel met Android-projecten. Voor unittesten volstaat het om de afhankelijkheid junit-jupiter toe te voegen in build.gradle. Instrumentele tests werken nog steeds via AndroidX Test Runner.
Minimaal is één annotatie @Test voor de methode voldoende. Voor initialisatie en opschonen worden @BeforeEach en @AfterEach aanbevolen, maar ze zijn niet verplicht.
Test Runner is de component van JUnit die de classpath scant, methoden met de @Test-annotatie vindt, instanties van testklassen maakt en de tests uitvoert. In JUnit 5 wordt deze rol vervuld door JUnit Platform met aangesloten Test Engines.
Gebruik assertThrows(Class, Executable) — het accepteert het type verwachte uitzondering en een lambda met de methodeaanroep. JUnit controleert of de uitzondering daadwerkelijk is gegooid en retourneert deze voor verdere controle.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook