Skip to content

Instantly share code, notes, and snippets.

@erikhuizinga
Created May 27, 2019 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erikhuizinga/031058b7781c64d4752f4e6d69c3ad9a to your computer and use it in GitHub Desktop.
Save erikhuizinga/031058b7781c64d4752f4e6d69c3ad9a to your computer and use it in GitHub Desktop.
Koin scoped view model
package com.example
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.koin.androidx.scope.currentScope
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.core.parameter.parametersOf
import org.koin.core.qualifier.named
import org.koin.core.scope.ScopeID
import org.koin.dsl.module
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
private const val ON_CLEARED = "MyViewModel#onCleared"
/**
* Requires at least:
* implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
*
* See also:
* https://developer.android.com/jetpack/androidx/releases/lifecycle#declaring_dependencies
*/
class MyViewModel(private val onClearedString: String) : ViewModel() {
fun function() = "function"
override fun onCleared() {
println(onClearedString)
Spy.text = onClearedString
super.onCleared()
}
}
object Spy {
lateinit var text: String
}
/**
* Requires:
* - koin-core
* - koin-androidx-viewmodel
* - koin-androidx-scope
*
* See also: https://insert-koin.io/docs/2.0/getting-started/introduction/
*/
class MyActivity : FragmentActivity() {
private val myViewModel: MyViewModel by viewModel { parametersOf(currentScope.id) }
fun function() = println(myViewModel.function())
override fun onDestroy() {
println("MyActivity#onDestroy")
super.onDestroy()
}
}
/**
* Requires:
* - JUnit 4.12
* - Robolectric 4.2.x: http://robolectric.org/getting-started/
*/
@RunWith(RobolectricTestRunner::class)
class ViewModelOnClearedTest {
@Before
fun before() {
val module = module {
scope(named<MyActivity>()) {
scoped {
"$ON_CLEARED for scope id = $id"
}
}
viewModel { (scopeID: ScopeID) ->
println("Instantiating MyViewModel for scope ID = $scopeID")
MyViewModel(getScope(scopeID).get())
}
}
startKoin {
// printLogger(Level.DEBUG) // Enable this to see what Koin does
modules(module)
}
}
@After
fun after() = stopKoin()
@Test
fun `MyViewModel#onCleared is called after last activity goes away`() {
val controller = Robolectric.buildActivity(MyActivity::class.java).setup()
val myActivity = controller.get()
val id = myActivity.currentScope.id
myActivity.function()
controller.destroy()
// Verify the Spy's text property is set correctly
assertEquals("$ON_CLEARED for scope id = $id", Spy.text)
// Also look at the console as some strings are printed, note the order of the prints
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment