Junit Tests for Coroutines APIs with Dagger Hilt
Home > coroutines-dagger-hilt-junit

Junit Tests for Coroutines APIs with Dagger Hilt Example

In this example we will see how we can write JUnit Tests for Coroutines APIs with Dagger Hilt, If you have not gone throught the part 1 of this please go to part 1 where we have implemented coroutines API calls with Hilt.


Part 1: Coroutines API call with Dagger Hilt

This is Part 2: JUnit Tests for APIs with Dagger Hilt


Here we will see how Dagger Hilt is simplifying Unit Testing.




Testing API Call Design


Let's Code:

Create this JsonProvider Object file under test package only

Create a json file in resources under test package (see the screenshot)

{
  "id": 783498333,
  "avatar_url": "https://avatars.githubusercontent.com/u/78355334983?v=4",
  "name": "Ravish Rajput",
  "location": "Bangalore",
  "public_repos": 1,
  "followers": 0,
  "url": ""
}
class FakeApiService @Inject constructor() : ApiServices {

    var failUserApi: Boolean = false
    var wrongResponse: Boolean = false

    override suspend fun getUser(): User {
        if (failUserApi) throw Exception("Api failed")
        val fakeResponse: User = JsonProvider.objectFromJsonFileWithType(USER_JSON)

        if (wrongResponse) return fakeResponse.apply {
            name = ""
        }

        return fakeResponse
    }

    companion object {
        private const val USER_JSON = "/json/user.json"
    }
}
@Module
@TestInstallIn(components = [SingletonComponent::class], replaces = [ApiServiceModule::class])
abstract class FakeApiServiceModule {

    @Binds
    @Singleton
    abstract fun providesApiServices(fakeApiService: FakeApiService): ApiServices
}
@HiltAndroidTest
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [25], application = HiltTestApplication::class)
@ExperimentalCoroutinesApi
@LooperMode(LooperMode.Mode.PAUSED)
class HomeViewModelTest {

    @get:Rule
    var hiltRule = HiltAndroidRule(this)

    @Inject
    lateinit var apiRepository: ApiRepository

    @BindValue
    @JvmField
    val fakeApiService: FakeApiService = FakeApiService()

    @Mock
    private lateinit var homeViewModel: HomeViewModel

    @Before
    fun setup() {
        hiltRule.inject()
        homeViewModel = HomeViewModel(apiRepository)
    }

    @Test
    fun `test User data success`() = runBlockingTest {
        homeViewModel.loadUserData()
        Shadows.shadowOf(Looper.getMainLooper()).idle()
        val value = homeViewModel.userFlow.value
        assertTrue(value is UIState.Success)
        assertNotNull(value.data)
        assertEquals(7834983, value.data?.id)
        assertEquals("Ravish Rajput", value.data?.name)
    }

    @Test
    fun `test User data api failure`() = runBlockingTest {
        fakeApiService.failUserApi = true
        homeViewModel.loadUserData()
        Shadows.shadowOf(Looper.getMainLooper()).idle()
        val value = homeViewModel.userFlow.value
        assertTrue(value is UIState.Error)
        assertNull(value.data)
    }

    @Test
    fun `test User wrong data`() = runBlockingTest {
        fakeApiService.wrongResponse = true
        homeViewModel.loadUserData()
        Shadows.shadowOf(Looper.getMainLooper()).idle()
        val value = homeViewModel.userFlow.value
        assertTrue(value is UIState.Success)
        assertNotNull(value.data)
        assertEquals("", value.data?.name)
    }

}


Test report

View Source