코루틴

    [Testing Coroutines] 코루틴 비동기 테스트가 어려운 이유

    코루틴이 멀티 스레드 환경에서 실행될 때 테스트가 어려운 이유 코루틴은 일반적으로 멀티 스레드 환경에서 비동기적으로 실행된다. 이 때문에 멀티 스레드 환경의 문제가 그대로 테스트에 나타난다. 그 대표적인 문제는 다음과 같다. 1. 함수 호출 순서 문제 2. 경쟁 상태 문제 3. 코루틴이 사용하는 디스패처 문제 함수 호출 순서 문제 멀티 스레드 환경에서 실행되는 함수들은 함수의 호출 순서를 파악하기 어렵다. 코루틴을 테스트 할 때도 이 문제가 나타나며, 병렬성으로 인해 실행을 코루틴이 실행되기 전에 다른 코루틴이 실행될 수 있다. 또한, 코루틴은 함께 실행되기 때문에 어떤 코드가 먼저 실행될지 파악하기 매우 어렵다. 예를 들어 하나의 코루틴이 일시 중단하게 되면 스레드를 다른 스레드가 사용할 수 있도록 양..

    [MockK] coEvery 사용해 목 객체의 일시 중단 함수에 대한 테스트 응답값 설정하기

    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..

    [Kotlin Coroutines] Log 를 사용한 Coroutines 디버깅

    로그를 사용한 디버깅의 필요성 Kotlin Coroutines는 같은 Coroutine Builder(launch, async 등) 의 중괄호 내부의 코드들이 다른 스레드에서 실행될 수 있다. 예를 들어 아래 코드에서 "task1 : start" 는 메인 스레드에서 실행되지만, "task1 : end"는 DefaultExecutor 스레드에서 실행된다. import kotlinx.coroutines.* fun main() = runBlocking { val task1 = launch(Dispatchers.Unconfined) { log("task1 : start") delay(100) log("task1 : end") } val task2 = launch { log("task2 : start") dela..

    [Kotlin Coroutines] IntelliJ 사용해 Coroutines 디버깅 하기

    디버깅을 하기 위한 준비 Kotlin Coroutines는 일시 중단 후에는 다른 스레드에서 실행될 수 있기 때문에 디버깅을 하기가 매우 어렵다. 이 글에서는 디버깅을 하기 어려운 예 중에 가장 간단한 예시를 제시할 것이다. 다음의 코드를 보자. import kotlinx.coroutines.* fun main() = runBlocking { launch(Dispatchers.Unconfined) { println("launch1 Working Thread : ${Thread.currentThread().name}") delay(100) println("launch1 Working Thread : ${Thread.currentThread().name}") } launch { println("launch2..

    [Coroutine Flow] 1. Flow란 무엇인가?

    Coroutine의 Flow는 데이터 스트림이며, 코루틴 상에서 리액티브 프로그래밍 지원 하기 위한 구성요소이다. 이를 이해하기 위해서는 먼저 리액티브(반응형) 프로그래밍이 무엇인지, 그리고 Flow가 리액티브 프로그래밍에 대응하여 어떠한 역할을 하는지를 알아야 한다. 리액티브 프로그래밍이란? 리액티브 프로그래밍이란 데이터가 변경 될 때 이벤트를 발생시켜서 데이터를 계속해서 전달하도록 하는 프로그래밍 방식을 뜻한다. 이는 기존의 명령형 프로그래밍과 대응되는 개념인데 이에 대한 내용은 [RxJava] 반응형 프로그래밍 이해하기 글에 잘 설명되어 있다. 만약 리액티브 프로그래밍에 대해 잘 모른다면 위 글을 읽고 오자. 기존 명령형 프로그래밍에서는 데이터의 소비자는 데이터를 요청한 후 받은 결과값을 일회성으로..