#前提・実現したいこと
Androidアプリ開発でkotlinでJunitテストを取り入れてみました。
下記のfun autoLoginTest()のverifyはpassすると思っていましたが、Coroutine周りで怒られているようです。
error内容について調べましたが、Coroutineについての理解が浅く解決できません。
なぜエラーになるのか、どうしたら解決できるのか教えていただきたいです。
よろしくお願いします。
###前提
presenterのautoLogin()についてのテストです
コード中のuserRepository.getUserProfile()はsuspend functionです。
architecture sampleのtodoアプリのtodo-mvp-coroutineを参考にしています
https://github.com/dmytrodanylyk/android-architecture/tree/todo-mvp-kotlin-coroutines
#発生している問題・エラーメッセージ
Argument(s) are different! Wanted: userRepository.getUserProfile( Continuation at com.example.gotcha2.autoLogin.AutoLoginPresenterTest$testAutoLogin$1.invokeSuspend(AutoLoginPresenterTest.kt:68) ); -> at com.example.gotcha2.data.source.repository.UserRepository.getUserProfile(UserRepository.kt:16) Actual invocation has different arguments: userRepository.getUserProfile( Continuation at com.example.gotcha2.autoLogin.AutoLoginPresenter$autoLogin$1.invokeSuspend(AutoLoginPresenter.kt:33) ); -> at com.example.gotcha2.autoLogin.AutoLoginPresenter$autoLogin$1.invokeSuspend(AutoLoginPresenter.kt:33) Comparison Failure: <Click to see difference>
#該当のソースコード
##コード
AutoLoginPresenter
kotlin
1class AutoLoginPresenter(private val userRepository: UserRepository, 2 private val autoLoginView: AutoLoginContract.View, 3 private val uiContext: CoroutineContext = 4Dispatchers.Main 5 ) 6 : AutoLoginContract.Presenter{ 7 init { 8 autoLoginView.presenter = this 9 } 10 11 override fun start() { 12 autoLogin() 13 } 14 15 private fun autoLogin() = launchSilent(uiContext){ 16 17 //realmからprofileを取ってきて、そのあとログイン処理を行う 18 19 val profileResult = userRepository.getUserProfile() 20 21// println(profileResult.toString()) 22 if (profileResult is Result.Success){ 23 24 val loginResult = userRepository.login(profileResult.data) 25 if(loginResult is Result.Success<UserProfile>){ 26 autoLoginView.transitionOriginFriend() 27 }else{ 28 autoLoginView.transitionLogin() 29 } 30 } 31 //アカウントがLocalに存在しない 32 else if(profileResult is Result.Error){ 33 autoLoginView.transitionCreateAccount() 34 }else{ 35 36 } 37 } 38}
CoroutineExt.kt
kotlin
1fun launchSilent( 2 context: CoroutineContext = Dispatchers.Main, 3 start: CoroutineStart = CoroutineStart.DEFAULT, 4 block: suspend CoroutineScope.() -> Unit 5) { 6 GlobalScope.launch(context, start, block) 7} 8 9/** 10 * Equivalent to [runBlocking] but return [Unit] instead of [T]. 11 * 12 * Mainly for usage when you want to lift [runBlocking] to return. Example: 13 * 14 * ``` 15 * override fun loadData() = runBlockingSilent { 16 * // code 17 * } 18 * ``` 19 */ 20fun <T> runBlockingSilent(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T) { 21 runBlocking(context, block) 22}
##テストコード
kotlin
1 2class AutoLoginPresenterTest { 3 4 @Mock private lateinit var userRepository: UserRepository 5 6 @Mock private lateinit var autoLoginView: AutoLoginContract.View 7 8 private lateinit var autoLoginPresenter: AutoLoginPresenter 9 10 private val EMAIL = "email" 11 12 private val PASSWORD = "password" 13 14 private val UID = "uid" 15 16 private val CREATED_AT: Timestamp = Timestamp.now() 17 18 private val USER_PROFILE = UserProfile(UID,CREATED_AT,EMAIL,PASSWORD) 19 20 21 @Before 22 fun setup(){ 23// Dispatchers.setMain(Dispatchers.Unconfined) 24 MockitoAnnotations.initMocks(this) 25 26 27 `when`(autoLoginView.isActive).thenReturn(true) 28 } 29 30 31 @Test 32 fun testAutoLogin() = runBlockingSilent { 33 `when`(userRepository.getUserProfile()).thenReturn(Result.Success(USER_PROFILE)) 34 `when`(userRepository.login(USER_PROFILE)).thenReturn(Result.Success(USER_PROFILE)) 35 36 autoLoginPresenter = AutoLoginPresenter(userRepository, autoLoginView, Unconfined).apply { start() } 37 //今回の問題 38 verify(userRepository).getUserProfile() 39 40 } 41 42}
#試したこと
#使っているツールのバージョンなど補足情報
回答1件
あなたの回答
tips
プレビュー