Skip to content

Commit 533eefe

Browse files
Merge pull request #4 from PhilippeBoisney/dev
Migrate to Koin
2 parents 78bbff7 + a1742e2 commit 533eefe

File tree

18 files changed

+89
-204
lines changed

18 files changed

+89
-204
lines changed

.DS_Store

0 Bytes
Binary file not shown.

android/app/build.gradle

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ android {
1111
minSdkVersion 21
1212
targetSdkVersion 28
1313
versionCode 1 // Will be overridden by Bitrise
14-
versionName "1.0.0-beta"
14+
versionName "1.0.1-beta"
1515
testInstrumentationRunner "io.nobullshit.nobullshit.TIRunner"
1616
}
1717
buildTypes {
@@ -48,13 +48,8 @@ dependencies {
4848
// GLIDE
4949
implementation "com.github.bumptech.glide:glide:$glide_version"
5050
kapt "com.github.bumptech.glide:compiler:$glide_version"
51-
// DAGGER 2
52-
implementation "com.google.dagger:dagger:$dagger_version"
53-
implementation "com.google.dagger:dagger-android:$dagger_version"
54-
implementation "com.google.dagger:dagger-android-support:$dagger_version"
55-
kapt "com.google.dagger:dagger-compiler:$dagger_version"
56-
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
57-
compileOnly 'javax.annotation:jsr250-api:1.0'
51+
// KOIN
52+
implementation "org.koin:koin-android:$koin_version"
5853
// CUSTOM TABS
5954
implementation "androidx.browser:browser:$custom_tab_version"
6055
// UNIT TEST
@@ -66,6 +61,5 @@ dependencies {
6661
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.1'
6762
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.1'
6863
androidTestImplementation "io.mockk:mockk-android:1.8.13"
69-
kaptAndroidTest 'com.google.dagger:dagger:2.17'
7064
}
7165
apply plugin: 'com.google.gms.google-services'
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
package io.nobullshit.nobullshit.base
22

33
import android.app.Application
4+
import org.koin.android.ext.android.startKoin
5+
import org.koin.dsl.module.Module
46

57
/**
6-
* We use a separate App for tests to prevent initializing dependency injection.
8+
* We use a separate [Application] for tests to prevent initializing release modules.
9+
* On the contrary, we will provide inside our tests custom [Module].
710
*
811
* See [io.nobullshit.nobullshit.TIRunner].
912
*/
10-
class TIBaseApplication : Application()
13+
class TIBaseApplication : Application() {
14+
override fun onCreate() {
15+
super.onCreate()
16+
startKoin(this, emptyList())
17+
}
18+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.nobullshit.nobullshit.di
2+
3+
import com.google.firebase.firestore.FirebaseFirestore
4+
import com.google.firebase.firestore.Query
5+
import io.mockk.mockk
6+
import io.nobullshit.nobullshit.db.dao.JobDao
7+
import io.nobullshit.nobullshit.model.Job
8+
import io.nobullshit.nobullshit.util.mockQuery
9+
import org.koin.dsl.module.module
10+
11+
/**
12+
* Remote [FirebaseFirestore] datasource only used for tests
13+
* @param listApprovedJobs: Mocked [Query] used to return a custom list of jobs.
14+
*/
15+
fun remoteDataSourceTestModule(listApprovedJobs: Query) = module {
16+
factory { mockk<FirebaseFirestore>(relaxed = true) }
17+
single {
18+
object : JobDao(get()) {
19+
override fun listApprovedJobs() = listApprovedJobs
20+
} as JobDao
21+
}
22+
}
Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,30 @@
11
package io.nobullshit.nobullshit.ui.joblist
22

3-
import android.content.Intent
4-
import androidx.browser.customtabs.CustomTabsIntent
5-
import androidx.recyclerview.widget.RecyclerView
63
import androidx.test.espresso.Espresso.onView
7-
import androidx.test.espresso.action.ViewActions.click
84
import androidx.test.espresso.assertion.ViewAssertions.matches
9-
import androidx.test.espresso.contrib.RecyclerViewActions
10-
import androidx.test.espresso.intent.Intents.intended
11-
import androidx.test.espresso.intent.Intents.intending
12-
import androidx.test.espresso.intent.matcher.IntentMatchers.*
13-
import androidx.test.espresso.intent.rule.IntentsTestRule
14-
import androidx.test.espresso.matcher.ViewMatchers
155
import androidx.test.espresso.matcher.ViewMatchers.*
166
import androidx.test.ext.junit.runners.AndroidJUnit4
177
import androidx.test.filters.LargeTest
188
import androidx.test.rule.ActivityTestRule
199
import com.google.firebase.firestore.*
20-
import io.mockk.*
2110
import io.nobullshit.nobullshit.Datasets
22-
import io.nobullshit.nobullshit.Datasets.SINGLE_JOB
2311
import io.nobullshit.nobullshit.R
2412
import io.nobullshit.nobullshit.db.dao.JobDao
13+
import io.nobullshit.nobullshit.di.remoteDataSourceTestModule
2514
import io.nobullshit.nobullshit.extension.getCategoryTitle
2615
import io.nobullshit.nobullshit.extension.getTypeTitle
27-
import io.nobullshit.nobullshit.model.Company
2816
import io.nobullshit.nobullshit.model.Job
2917
import io.nobullshit.nobullshit.testing.SingleFragmentActivity
3018
import io.nobullshit.nobullshit.util.*
3119
import org.hamcrest.CoreMatchers.allOf
3220
import org.hamcrest.CoreMatchers.not
33-
21+
import org.junit.After
3422
import org.junit.Test
3523
import org.junit.runner.RunWith
36-
3724
import org.junit.Rule
25+
import org.koin.standalone.StandAloneContext.loadKoinModules
26+
import org.koin.standalone.StandAloneContext.stopKoin
27+
import org.koin.dsl.module.Module
3828

3929
/**
4030
* Instrumented tests for [JobListFragment]
@@ -45,11 +35,16 @@ class TIJobList {
4535

4636
@Rule
4737
@JvmField
48-
val activityRule = IntentsTestRule(SingleFragmentActivity::class.java, true, true)
38+
val activityRule = ActivityTestRule(SingleFragmentActivity::class.java, true, true)
39+
40+
@After
41+
fun tearDown(){
42+
stopKoin()
43+
}
4944

5045
@Test
5146
fun testLoadingSingleJob() {
52-
this.configureFragmentBeforeTest(mockQuery(Job::class.java, Datasets.SINGLE_JOB))
47+
this.configureCustomDependencies(mockQuery(Job::class.java, Datasets.SINGLE_JOB))
5348

5449
onView(withId(R.id.fragment_job_list_refresh)).check(matches(not(isRefreshing())))
5550
onView(withId(R.id.fragment_job_list_rv)).check(matches((hasItemCount(1))))
@@ -62,44 +57,31 @@ class TIJobList {
6257

6358
@Test
6459
fun testLoadingMultipleJob() {
65-
this.configureFragmentBeforeTest(mockQuery(Job::class.java, *Datasets.MULTIPLE_JOBS))
60+
this.configureCustomDependencies(mockQuery(Job::class.java, *Datasets.MULTIPLE_JOBS))
6661

6762
onView(withId(R.id.fragment_job_list_refresh)).check(matches(not(isRefreshing())))
6863
onView(withId(R.id.fragment_job_list_rv)).check(matches((hasItemCount(30))))
6964
}
7065

7166
@Test
7267
fun testLoadingNothing() {
73-
this.configureFragmentBeforeTest(mockQuery(Job::class.java))
68+
this.configureCustomDependencies(mockQuery(Job::class.java))
7469

7570
onView(withId(R.id.fragment_job_list_refresh)).check(matches(not(isRefreshing())))
7671
onView(withId(R.id.fragment_job_list_rv)).check(matches((hasItemCount(0))))
7772
}
7873

79-
@Test
80-
fun testClickOnJob() {
81-
this.configureFragmentBeforeTest(mockQuery(Job::class.java, Datasets.SINGLE_JOB))
82-
83-
onView(withId(R.id.fragment_job_list_rv)).perform(RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(0, click()))
84-
intended(hasAction(Intent.ACTION_VIEW))
85-
intended(hasData(Datasets.SINGLE_JOB.url))
86-
}
87-
8874
// ---
8975

9076
/**
91-
* Create a new [JobListFragment]
92-
* and mock the [JobDao] with custom response [Query].
77+
* Configure custom [Module] for each [Test]
78+
* and provide a [JobDao] with custom mocked response [Query].
79+
*
9380
* The fragment will be set inside a fake activity [SingleFragmentActivity]
9481
*/
95-
private fun configureFragmentBeforeTest(query: Query) {
96-
val fragment = JobListFragment().apply {
97-
val firestore = mockk<FirebaseFirestore>()
98-
jobDao = object : JobDao(firestore) {
99-
override fun listApprovedJobs() = query
100-
}
101-
}
102-
activityRule.activity.setFragment(fragment)
82+
private fun configureCustomDependencies(query: Query) {
83+
loadKoinModules(remoteDataSourceTestModule(query))
84+
this.activityRule.activity.setFragment(JobListFragment())
10385
}
10486
}
10587

android/app/src/main/java/io/nobullshit/nobullshit/MainActivity.kt

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,19 @@ package io.nobullshit.nobullshit
22

33
import androidx.appcompat.app.AppCompatActivity
44
import android.os.Bundle
5-
import androidx.fragment.app.Fragment
6-
import dagger.android.DispatchingAndroidInjector
7-
import dagger.android.support.HasSupportFragmentInjector
85
import io.nobullshit.nobullshit.ui.joblist.JobListFragment
9-
import javax.inject.Inject
106

117
/**
128
* A simple activity that holds the [JobListFragment] fragment
139
*/
14-
class MainActivity : AppCompatActivity(), HasSupportFragmentInjector {
15-
16-
@Inject
17-
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
10+
class MainActivity : AppCompatActivity() {
1811

1912
override fun onCreate(savedInstanceState: Bundle?) {
2013
super.onCreate(savedInstanceState)
2114
setContentView(R.layout.activity_main)
2215
this.configureAndShowFragment()
2316
}
2417

25-
override fun supportFragmentInjector() = dispatchingAndroidInjector
26-
2718
// ---
2819

2920
private fun configureAndShowFragment() {
Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
package io.nobullshit.nobullshit.base
22

3-
import android.app.Activity
43
import android.app.Application
5-
import dagger.android.DispatchingAndroidInjector
6-
import dagger.android.HasActivityInjector
7-
import io.nobullshit.nobullshit.di.AppInjector
8-
import javax.inject.Inject
9-
10-
class BaseApplication: Application(), HasActivityInjector {
11-
@Inject
12-
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
4+
import io.nobullshit.nobullshit.di.appComponents
5+
import org.koin.android.ext.android.startKoin
136

7+
class BaseApplication: Application() {
148
override fun onCreate() {
159
super.onCreate()
16-
AppInjector.init(this)
10+
startKoin(this, appComponents)
1711
}
18-
19-
override fun activityInjector() = dispatchingAndroidInjector
2012
}

android/app/src/main/java/io/nobullshit/nobullshit/di/AppComponent.kt

Lines changed: 0 additions & 28 deletions
This file was deleted.

android/app/src/main/java/io/nobullshit/nobullshit/di/AppInjector.kt

Lines changed: 0 additions & 49 deletions
This file was deleted.

android/app/src/main/java/io/nobullshit/nobullshit/di/DataModule.kt

Lines changed: 0 additions & 16 deletions
This file was deleted.

android/app/src/main/java/io/nobullshit/nobullshit/di/FragmentBuildersModule.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.

android/app/src/main/java/io/nobullshit/nobullshit/di/Injectable.kt

Lines changed: 0 additions & 6 deletions
This file was deleted.

android/app/src/main/java/io/nobullshit/nobullshit/di/MainActivityModule.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package io.nobullshit.nobullshit.di
2+
3+
import org.koin.dsl.module.Module
4+
import org.koin.dsl.module.module
5+
6+
/**
7+
* App Components
8+
*/
9+
val appComponents: List<Module> = listOf(remoteDataSourceModule)

0 commit comments

Comments
 (0)