Mockito로 여러 개의 method 모듈을 만들 때 주의사항
하고 싶은 일
예를 들어, CatRepository라는 class가 NyaoDataSource라는 class에 의존한다고 가정해 봅시다.
이때
CatRepository.kt
@RunWith(MockitoJUnitRunner::class)
class CatRepository @Inject constructor(
val nyaoDataSource: NyaoDataSource
): CatRepository {
// 指定の猫が鳴けるかどうかを確認する
override suspend fun getChirp(baseCat: BaseCat): CatInfo {
if (nyaoDataSource.checkChirp(baseCat.nameCat) == true) {
return nyaoDataSource.getChirp(baseCat.nameCat)
}
throw IllegalStateException("This cannot chirp...sorry.")
}
}
이렇게 쓸 수 있지만 이method를 테스트하려면 nyaoDataSource.checkChirp
와nyaoDataSource.getChirp
두 개의 모델로 테스트해야 한다.그래서 이번에 하고 싶은 것은'모키토로 여러 메트로이드를 적절히 만드는 모듈'이다.
최초로 제작된 코드(의외의 동작을 한 코드)
우선 의외의 동작을 한 코드입니다.
CatRepositoryTest.kt
...中略
private val mockNyaoLocal = mock(NyaoDataSource::class.java)
@Test
fun getAuthInfoTest() {
runBlocking {
val inputDummy = BaseCat(
nameCat = "Tama",
cate = "mike",
)
mockNyaoLocal.apply {
`when`(checkChirp(inputDummy.nameCat)).thenReturn(false)
`when`(getAccountInfo(inputDummy.nameCat))
.thenThrow(IllegalArgumentException("この猫はいない。いるかどうか、チェックしてから使ってね."))
}
val catRepositoryImpl = CatRepositoryImpl(mockNyaoLocal)
val e: IllegalStateException
= assertThrows(IllegalStateException::class.java){
runBlocking {
catRepositoryImpl.getChirp(inputDummy)
}
}
assertEquals("この猫はいないよ。",
e.message)
}
}
}
이 결과는 반드시 통과해야 할 테스트는 통과하지 못한다.왜냐면,CatRepository.kt의if문에서의 처리도 집행되었다(실제로 집행된 것이 아니라 그 행위는 다음과 같은 추측이다).여기서 이상한 것은CatRepositoryTest입니다.kt에서.
mockNyaoLocal.apply {
`when`(checkChirp(inputDummy.nameCat)).thenReturn(false)
`when`(getAccountInfo(inputDummy.nameCat))
.thenThrow(IllegalArgumentException("この猫はいない。いるかどうか、チェックしてから使ってね."))
}
이 부분.when의 어떤 조건에 부합되면 apply의 모든 것이 실행됩니다.Mockito의 Reference를 찾아보았지만 좋은 것을 찾지 못했고 apply의 행동을 조사한 결과[1][2]는 이해하기 어려웠기 때문에 제 추측이 정확한지 누가 알려주면 좋겠어요.이동 코드
이동하는 코드는 다음과 같습니다.
CatRepositoryTest.kt
...中略
private val mockNyaoLocal = mock(NyaoDataSource::class.java)
@Test
fun getAuthInfoTest() {
runBlocking {
val inputDummy = BaseCat(
nameCat = "Tama",
cate = "mike",
)
doReturn(false)
.`when`(mockNyaoLocal)
.checkChirp(inputDummy.nameCat)
doReturn(IllegalArgumentException("この猫はいない。いるかどうか、チェックしてから使ってね."))
.`when`(mockNyaoLocal)
.getChirp(inputDummy.nameCat)
val catRepositoryImpl = CatRepositoryImpl(mockNyaoLocal)
val e: IllegalStateException
= assertThrows(IllegalStateException::class.java){
runBlocking {
catRepositoryImpl.getChirp(inputDummy)
}
}
assertEquals("この猫はいないよ。",
e.message)
}
}
}
방금 잘 돌아가지 못한 코드(으)로 변경합니다.이렇게 하면 각자의 when이 독립적으로 움직여 기대하는 운동을 실현할 수 있다.
하지만 stub를 사용하지 않아 컴파일러에게 욕을 먹기 때문에 이번에는 아래의 Exception이 필요하지 않다.
각주
Kotlin 역할 영역 함수 용도 요약/@ngswtarohttps://qiita.com/ngsw_taro/items/d29e3080d9fc8a38691e(2022-01-16열람)↩︎
Kotlin의 let (), apply (),run (), with () 를 자유롭게 사용하기/Masamichii Yoshii http://extra-vision.blogspot.com/2016/11/kotlin-let-apply-run-with.html ↩︎
Reference
이 문제에 관하여(Mockito로 여러 개의 method 모듈을 만들 때 주의사항), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/akira_kashihara/articles/e3e329f419b4cc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)