코루틴이 멀티 스레드 환경에서 실행될 때 테스트가 어려운 이유 코루틴은 일반적으로 멀티 스레드 환경에서 비동기적으로 실행된다. 이 때문에 멀티 스레드 환경의 문제가 그대로 테스트에 나타난다. 그 대표적인 문제는 다음과 같다. 1. 함수 호출 순서 문제 2. 경쟁 상태 문제 3. 코루틴이 사용하는 디스패처 문제 함수 호출 순서 문제 멀티 스레드 환경에서 실행되는 함수들은 함수의 호출 순서를 파악하기 어렵다. 코루틴을 테스트 할 때도 이 문제가 나타나며, 병렬성으로 인해 실행을 코루틴이 실행되기 전에 다른 코루틴이 실행될 수 있다. 또한, 코루틴은 함께 실행되기 때문에 어떤 코드가 먼저 실행될지 파악하기 매우 어렵다. 예를 들어 하나의 코루틴이 일시 중단하게 되면 스레드를 다른 스레드가 사용할 수 있도록 양..
유닛 테스팅
every를 사용해 응답값을 설정할 때의 문제점 이전 글에서 다루었던 UserProfileFetcher이 리모트 저장소로부터 데이터를 가져오는 I/O 작업을 한다고 가정하고, 함수를 모두 다음과 같이 일시 중단 함수로 바꿔보자. class UserProfileFetcher( private val userRepository: UserRepository, ) { suspend fun getUserProfileById(id: String): UserProfile { return UserProfile( id = id, name = userRepository.getNameByUserId(id) ) } } interface UserRepository { suspend fun saveUserName(id: Strin..
입력값을 특정 값으로 지정하는 것의 한계 입력값을 다음과 같이 지정하게 되면, getNameByUserId에 0xffffffff이 입력되었을 때만 "TestUser"이 반환된다. every { userRepository.getNameByUserId("0xffffffff") } returns "TestUser" 그렇다면 만약 유효한 아이디 일 경우에 "TestUser"을 반환하고, 유효하지 않은 아이디일 경우에는 예외를 반환하는 목 객체는 어떻게 만들 수 있을까? 만약 유효한 아이디가 8자리의 16진수값이라면, 이에 대한 모든 값에 대해 every를 작성하게 되면 수십억줄의 코드를 작성해야 할 수 있다. 이런 경우 만약 입력 값을 특정 범위로 지정할 수 있다면 매우 도움이 될 것이다. 이를 위해 MockK..
MockK란 무엇인가? MockK는 코틀린에서 테스트 시 목(Mock) 객체를 생성하는 것을 돕는 라이브러리이다. 기존에 목 객체를 만들기 위해서는 인터페이스를 목 클래스로 직접 구현을 해야 했는데, MockK를 사용하면 간단하게 목 객체를 생성할 수 있다. Gradle에 MockK 의존성 추가하기 Gradle에 MockK에 대한 의존성은 다음과 같이 추가해주면 된다. dependencies { ... // MockK 라이브러리 testImplementation("io.mockk:mockk:1.13.8") } MockK의 사용 MockK를 사용하는 것은 매우 간단하다. 예를 들어 다음과 같은 UserProfileFetcher이 있다고 해보자. class UserProfileFetcher( private ..
안드로이드 메서드를 사용할 때 생기는 문제점과 원인 안드로이드 전용 클래스의 정적 메서드를 클래스 내부에서 사용한다면 테스트 시 문제가 생긴다. 예를 들어 다음과 같은 테스트 코드를 보자. import android.text.TextUtils import org.junit.Assert.assertTrue import org.junit.Test class ExampleUnitTest { @Test fun testTextIsEmpty() { val isEmpty = TextUtils.isEmpty("") assertTrue(isEmpty) } } 이 테스트는 매우 간단한 테스트로, TextUtils.isEmpty를 호출해 매개 변수로 입력된 문자열이 빈칸인지 확인하기 위한 테스트이다. 하지만 이 테스트를 실..