Android Unit Test Using Junit 5
Unit Test
In the Testing is Part of Android Development already define what is Unit Test. Better read it before continue this article.
For remaind you, Unit Test have definition are :
- Focus tests isolate one class.
- Assume class dependencies are already working correctly.
- Independent from Android framework / third party.
- Run under JVM.
Overview
For this part will be guide you to Combine Junit4 and Junit5. Android as default using JUnit 4, but if we want to get more feature from JUnit5 why not?.
Step by step
Add Junit 4 and Junit 5 to Android Project
this configuration on app/build.gradle
:
1
2plugins {
3 id "de.mannodermaus.android-junit5" version "1.8.2.1"
4}
5
6dependencies {
7
8 //Junit5
9 testImplementation "org.junit.jupiter:junit-jupiter-api:5.8.2"
10 testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.8.2"
11
12 // (Optional) if you need "Parameterized Tests"
13 testImplementation "org.junit.jupiter:junit-jupiter-params:5.8.2"
14
15 //Junit4
16 testImplementation "junit:junit:4.13.2"
17 testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.8.2"
18}
this configuration on /build.gradle
:
1buildscript {
2 dependencies {
3 classpath "de.mannodermaus.android-junit5:1.8.2.1"
4 }
5}
Detail docummentation please see android-junit5.
JVM test only
I assume this unit test run on the JVM, no Robolectic or Android. Please add on app/build.gradle
:
1
2android {
3 testOptions {
4 unitTests.all {
5 useJunitPlatform()
6 }
7 }
8}
Let’s writting the test
This part will be written by Junit4. We test UserRepository class, the class have dependecies to UserLocalDataSource and UserRemoteDataSource. I mocking the dependecies using Mockk.io. if you see comments, i’m describe what we need changes.
1// we do not need @RunWith because it's replaced by @ExtendWith.
2class UserRepositoryTest {
3
4 private val local: UserLocalDataSource = mockk()
5
6 private val remote: UserRemoteDataSource = mockk()
7
8 private val repository: UserRepository = UserRepository(local, remote)
9
10
11 // @Before and @After replaced with @BeforeEach and @AfterEach
12 @Before
13 fun setup() {
14 clearMock(local, remote)
15 }
16
17 @After
18 fun tear() {
19 }
20
21 // Use @Test from org.junit.jupiter.api.Test instead of org.junit.Test
22 @Test
23 fun `When repository no local then query to remote then should be success`(){
24 }
25
26 // If we want to group several test cases, use @Nested for grouping
27 @Nested
28 inner class LocalDataSourceSpec {
29 }
30}
- Change the import
If we use JUnit5 don’t forget changing import for @Test
1// Before
2import org.junit.Test
3
4// After
5import org.junit.jupiter.api.Test
@Before
replace to@BeforeEach
Junit5 have lifecycle each function or class, I’m prefer using each function. so every test in function before run it will trigger @BeforeEach
.
@After
replace to@AfterEach
That are same like @BeforeEach
, this is will be execute After one function done exacute the test.
- Grouping the test using
@Nested
JUnit5 introduces @Nested, allowing you to group a set of tests into an inner class.