반환 값은 하나만 정의 할 수있는 것 같습니다.
현재 getStore
는를 사용하여 매개 변수로 삽입 된 확장 값을 저장합니다 ParameterResolver
. 이 예제에서는 TestCoroutineDispatcher
로컬 JUnit 테스트에서 Coroutine 라이프 사이클을 관리하기 위해 주입됩니다. 동일한 확장에서 두 번째 값을 삽입해야하는 경우에는 어떻습니까?
Test.kt
@ExtendWith(LifecycleExtensions::class)
// The TestCoroutineDispatcher is injected here as a parameter.
class FeedLoadContentTests(val testDispatcher: TestCoroutineDispatcher) {
private val contentViewModel = ContentViewModel()
private fun FeedLoad() = feedLoadTestCases()
@ParameterizedTest
@MethodSource("FeedLoad")
fun `Feed Load`(test: FeedLoadContentTest) = testDispatcher.runBlockingTest {
// Some testing done here.
}
}
Extension.kt
class LifecycleExtensions : BeforeAllCallback, AfterAllCallback, BeforeEachCallback,
AfterEachCallback, ParameterResolver {
...
override fun beforeEach(context: ExtensionContext?) {
// Set Coroutine Dispatcher.
Dispatchers.setMain(context?.getStore(STORE_NAMESPACE)
?.get(STORE_KEY, TestCoroutineDispatcher::class.java)!!)
...
}
override fun afterEach(context: ExtensionContext?) {
// Reset Coroutine Dispatcher.
Dispatchers.resetMain()
context?.getStore(STORE_NAMESPACE)
?.get(STORE_KEY, TestCoroutineDispatcher::class.java)!!.cleanupTestCoroutines()
...
}
override fun supportsParameter(parameterContext: ParameterContext?,
extensionContext: ExtensionContext?) =
parameterContext?.parameter?.type == TestCoroutineDispatcher::class.java
override fun resolveParameter(parameterContext: ParameterContext?,
extensionContext: ExtensionContext?) =
TestCoroutineDispatcher().apply {
extensionContext?.getStore(STORE_NAMESPACE)?.put(STORE_KEY, this)
}
}
@Slaw 통찰력에 감사드립니다 !
음, #supportsParameter 및 #resolveParameter는 메서드의 각 매개 변수에 대해 호출됩니다. 따라서 현재 매개 변수 유형이 TestCoroutineDispatcher인지 확인하는 테스트가 있습니다. 즉, 공유 된 ViewModel 유형에 대한 테스트를 추가 할 수 있습니다. 그런 다음 유형에 따라 올바른 매개 변수를 해결하십시오. 여러 테스트에서 ViewModel을 공유하려면 부모 / 루트 ExtensionContext.Store에 참조를 저장할 수 있습니다.
Test.kt
@ExtendWith(LifecycleExtensions::class)
// The TestCoroutineDispatcher is injected here as a parameter.
class FeedLoadContentTests(val testDispatcher: TestCoroutineDispatcher, val contentViewModel: ContentViewModel) {
private fun FeedLoad() = feedLoadTestCases()
@ParameterizedTest
@MethodSource("FeedLoad")
// Injected testDispatcher used here.
fun `Feed Load`(test: FeedLoadContentTest) = testDispatcher.runBlockingTest {
// Some testing done here.
// Injected contentViewModel used here.
}
}
Extension.kt
class LifecycleExtensions : BeforeAllCallback, AfterAllCallback, BeforeEachCallback,
AfterEachCallback, ParameterResolver {
override fun beforeEach(context: ExtensionContext?) {
// Set Coroutine Dispatcher.
Dispatchers.setMain(context?.root
?.getStore(TEST_COROUTINE_DISPATCHER_NAMESPACE)
?.get(TEST_COROUTINE_DISPATCHER_KEY, TestCoroutineDispatcher::class.java)!!)
// Set ViewModel
context?.root
?.getStore(VIEWMODEL_NAMESPACE)
?.get(CONTENT_VIEWMODEL_KEY, ContentViewModel::class.java)!!
// Set LiveData Executor.
ArchTaskExecutor.getInstance().setDelegate(object : TaskExecutor() {
override fun executeOnDiskIO(runnable: Runnable) = runnable.run()
override fun postToMainThread(runnable: Runnable) = runnable.run()
override fun isMainThread(): Boolean = true
})
}
override fun afterEach(context: ExtensionContext?) {
// Reset Coroutine Dispatcher.
Dispatchers.resetMain()
context?.root
?.getStore(TEST_COROUTINE_DISPATCHER_NAMESPACE)
?.get(TEST_COROUTINE_DISPATCHER_KEY, TestCoroutineDispatcher::class.java)!!
.cleanupTestCoroutines()
// Clear LiveData Executor
ArchTaskExecutor.getInstance().setDelegate(null)
}
override fun resolveParameter(parameterContext: ParameterContext?,
extensionContext: ExtensionContext?) =
if (parameterContext?.parameter?.type == TestCoroutineDispatcher::class.java)
getTestCoroutineDispatcher(extensionContext).let { dipatcher ->
if (dipatcher == null) saveAndReturnTestCoroutineDispatcher(extensionContext)
else dipatcher
}
else getViewModel(extensionContext).let { viewModel ->
if (viewModel == null) saveAndReturnContentViewModel(extensionContext)
else viewModel
}
private fun getTestCoroutineDispatcher(context: ExtensionContext?) = context?.root
?.getStore(TEST_COROUTINE_DISPATCHER_NAMESPACE)
?.get(TEST_COROUTINE_DISPATCHER_KEY, TestCoroutineDispatcher::class.java)
private fun saveAndReturnTestCoroutineDispatcher(extensionContext: ExtensionContext?) =
TestCoroutineDispatcher().apply {
extensionContext?.root
?.getStore(TEST_COROUTINE_DISPATCHER_NAMESPACE)
?.put(TEST_COROUTINE_DISPATCHER_KEY, this)
}
private fun getViewModel(context: ExtensionContext?) = context?.root
?.getStore(VIEWMODEL_NAMESPACE)
?.get(CONTENT_VIEWMODEL_KEY, ContentViewModel::class.java)
private fun saveAndReturnContentViewModel(extensionContext: ExtensionContext?) =
ContentViewModel().apply {
extensionContext?.root
?.getStore(VIEWMODEL_NAMESPACE)
?.put(CONTENT_VIEWMODEL_KEY, ContentViewModel())
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다