Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Serchinastico committed Mar 7, 2019
1 parent 377920d commit 525139d
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 42 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ dependencies {
implementation "android.arch.navigation:navigation-fragment-ktx:1.0.0-beta01"
implementation "android.arch.navigation:navigation-ui-ktx:1.0.0-beta01"
implementation "androidx.room:room-runtime:2.1.0-alpha04"
implementation "android.arch.work:work-runtime:1.0.0-beta04"
implementation "android.arch.work:work-runtime-ktx:1.0.0-beta05"
kapt "androidx.room:room-compiler:2.1.0-alpha04"
implementation "androidx.fragment:fragment:1.1.0-alpha03"
debugImplementation "androidx.fragment:fragment-testing:1.1.0-alpha03"
Expand All @@ -83,7 +83,7 @@ dependencies {
androidTestImplementation "androidx.test.espresso:espresso-contrib:3.1.1"
androidTestImplementation "androidx.test.espresso:espresso-intents:3.1.1"
androidTestImplementation "androidx.room:room-testing:2.1.0-alpha04"
androidTestImplementation "android.arch.work:work-testing:1.0.0-beta04"
androidTestImplementation "android.arch.work:work-testing:1.0.0-beta05"
}

shot {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,29 @@ import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
import com.karumi.jetpack.superheroes.R
import com.karumi.jetpack.superheroes.SuperHeroesApplication
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.mock
import org.junit.Before
import org.junit.runner.RunWith
import org.kodein.di.Kodein
import org.kodein.di.erased.bind
import org.kodein.di.erased.instance
import org.mockito.MockitoAnnotations
import java.util.concurrent.ExecutorService
import java.util.concurrent.FutureTask
import java.util.concurrent.Executor

@LargeTest
@RunWith(AndroidJUnit4::class)
abstract class FragmentTest<F : Fragment> : ScreenshotTest {

abstract val fragmentBlock: () -> F

private val executorServiceOnUiThread = mock<ExecutorService> {
on(it.execute(any())).thenAnswer { invocation ->
InstrumentationRegistry.getInstrumentation().runOnMainSync {
(invocation.getArgument(0) as Runnable).run()
}
FutureTask { null }
}
}

@Before
fun setup() {
MockitoAnnotations.initMocks(this)
val app = ApplicationProvider.getApplicationContext<SuperHeroesApplication>()
app.override(Kodein.Module("Base test dependencies", allowSilentOverride = true) {
import(testDependencies, allowOverride = true)
bind<ExecutorService>() with instance(executorServiceOnUiThread)
bind<Executor>() with instance(Executor {
InstrumentationRegistry.getInstrumentation().runOnMainSync { it.run() }
})
})
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.karumi.jetpack.superheroes.worker

import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.testing.WorkManagerTestInitHelper
import com.karumi.jetpack.superheroes.SuperHeroesApplication
import com.karumi.jetpack.superheroes.common.SuperHeroesDatabase
import com.karumi.jetpack.superheroes.data.repository.room.SuperHeroEntity
import com.karumi.jetpack.superheroes.domain.model.SuperHero
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.kodein.di.Kodein
import org.kodein.di.erased.bind
import org.kodein.di.erased.instance
import java.util.concurrent.Executor

class ThanosWorkerTest {

private lateinit var database: SuperHeroesDatabase

@Before
fun setUp() {
val app = ApplicationProvider.getApplicationContext<SuperHeroesApplication>()
WorkManagerTestInitHelper.initializeTestWorkManager(app)
database = Room.inMemoryDatabaseBuilder(app, SuperHeroesDatabase::class.java)
.allowMainThreadQueries()
.build()
app.override(Kodein.Module("Test dependencies", allowSilentOverride = true) {
bind<SuperHeroesDatabase>() with instance(database)
bind<Executor>() with instance(Executor {
getInstrumentation().runOnMainSync { it.run() }
})
})
database.superHeroesDao().deleteAll()
}

@Test
fun thanosWorkerDoNotDeleteAnyoneIfSuperHeroesAreLessThanTwo() {
val superHeroes = insertSuperHeroes(1)

enqueueWorker()

assertEquals(superHeroes, getInsertedSuperHeroes())
}

@Test
fun thanosWorkerDeletesHalfTheSuperHeroesWhenThereAreMoreThanTwo() {
insertSuperHeroes(10)

enqueueWorker()

assertEquals(5, getInsertedSuperHeroes().size)
}

@Test
fun thanosWorkerDeletesHalfTheSuperHeroesRoundingDownWhenThereIsAnOddNumberOfSuperHeroes() {
insertSuperHeroes(11)

enqueueWorker()

assertEquals(6, getInsertedSuperHeroes().size)
}

private fun enqueueWorker() = getInstrumentation().runOnMainSync {
val work = OneTimeWorkRequest.Builder(ThanosWorker::class.java).build()
WorkManager.getInstance().enqueue(work)
}

private fun insertSuperHeroes(numberOfSuperHeroes: Int): List<SuperHero> {
val superHeroes = (1..numberOfSuperHeroes)
.map { SuperHero("#$it", "SH $it", null, false, "") }

database.superHeroesDao().insertAll(superHeroes.map { SuperHeroEntity(it) })

return superHeroes
}

private fun getInsertedSuperHeroes(): List<SuperHero> =
database.superHeroesDao().getAllSuperHeroes().map { it.superHero }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.karumi.jetpack.superheroes

import android.app.Application
import androidx.work.OneTimeWorkRequest
import androidx.work.PeriodicWorkRequest
import androidx.work.PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS
import androidx.work.WorkManager
import com.karumi.jetpack.superheroes.common.SuperHeroesDatabase
import com.karumi.jetpack.superheroes.common.module
Expand All @@ -19,8 +20,9 @@ import org.kodein.di.erased.bind
import org.kodein.di.erased.instance
import org.kodein.di.erased.provider
import org.kodein.di.erased.singleton
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit

class SuperHeroesApplication : Application(), KodeinAware {
override var kodein = Kodein.lazy {
Expand All @@ -34,8 +36,11 @@ class SuperHeroesApplication : Application(), KodeinAware {
}

private fun startThanosWork() {
val work = OneTimeWorkRequest.Builder(ThanosWorker::class.java)
.build()
val work = PeriodicWorkRequest.Builder(
ThanosWorker::class.java,
MIN_PERIODIC_INTERVAL_MILLIS,
TimeUnit.MILLISECONDS
).build()
WorkManager.getInstance().enqueue(work)
}

Expand Down Expand Up @@ -67,7 +72,7 @@ class SuperHeroesApplication : Application(), KodeinAware {
bind<RemoteSuperHeroDataSource>() with provider {
RemoteSuperHeroDataSource(instance())
}
bind<ExecutorService>() with provider {
bind<Executor>() with provider {
Executors.newCachedThreadPool()
}
bind<DKodein>() with provider { this }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package com.karumi.jetpack.superheroes.data.repository

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import com.karumi.jetpack.superheroes.data.repository.room.SuperHeroDao
import com.karumi.jetpack.superheroes.data.repository.room.SuperHeroEntity
import com.karumi.jetpack.superheroes.domain.model.SuperHero
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executor

class LocalSuperHeroDataSource(
private val dao: SuperHeroDao,
private val executor: ExecutorService
private val executor: Executor
) {
fun getAllSuperHeroes(
pageSize: Int,
Expand All @@ -36,20 +35,7 @@ class LocalSuperHeroDataSource(
return superHero
}

fun deleteRandomHalf() = executor.execute {
val superHeroes = dao.getAllSuperHeroes()

if (superHeroes.size < 2) {
return@execute
}

val randomSuperHeroIds = superHeroes
.shuffled()
.take(superHeroes.size / 2)
.map { it.superHero.id }
Log.d("GERSIO", "Deleting: $randomSuperHeroIds")
dao.deleteAll(randomSuperHeroIds)
}
fun deleteRandomHalf() = dao.deleteHalf()

private fun SuperHeroEntity.toSuperHero(): SuperHero = superHero
private fun SuperHero.toEntity(): SuperHeroEntity = SuperHeroEntity(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package com.karumi.jetpack.superheroes.data.repository
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.karumi.jetpack.superheroes.domain.model.SuperHero
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executor

class RemoteSuperHeroDataSource(
private val executor: ExecutorService
private val executor: Executor
) {
companion object {
private const val BIT_TIME = 1500L
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update

@Dao
Expand All @@ -30,4 +31,20 @@ interface SuperHeroDao {

@Query("DELETE FROM superheroes WHERE superhero_id IN (:ids)")
fun deleteAll(ids: List<String>)

@Transaction
fun deleteHalf() {
val superHeroes = getAllSuperHeroes()

if (superHeroes.size < 2) {
return
}

val randomSuperHeroIds = superHeroes
.shuffled()
.take(superHeroes.size / 2)
.map { it.superHero.id }

deleteAll(randomSuperHeroIds)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.karumi.jetpack.superheroes.worker

import android.content.Context
import android.util.Log
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.karumi.jetpack.superheroes.data.repository.LocalSuperHeroDataSource
Expand All @@ -18,7 +17,6 @@ class ThanosWorker(
private val localSuperHeroesDataSource: LocalSuperHeroDataSource by instance()

override fun doWork(): Result {
Log.d("GERSIO", "doWork!")
localSuperHeroesDataSource.deleteRandomHalf()
return Result.success()
}
Expand Down

0 comments on commit 525139d

Please sign in to comment.