코틀린 예외처리를 보다가 흠.. 이런게 있구나.. 하고 남김.
특정 클래스에서 숫자형 문자를 반환하고 반환된 문자를 Int형으로 변경하는 상황으로 테스트코드 작성.
internal class TextNumber {
// 임의 Throw
fun getThrow() : String {
throw RuntimeException()
}
// 정상반환
fun getStringNumber() : String = "1000"
}
예시:
기본적인 try ~ catch를 사용했을 경우 의 코드 ( 오래전.. )
internal class RunCatchingService {
private val log = KotlinLogging.logger { }
// throw
fun getAsis() : Int {
val textNumber = TextNumber()
try {
return textNumber.getThrow().toInt()
}catch (e: RuntimeException){
log.error { "$e" }
throw RuntimeException()
}
}
.....
위에 코드가 보기에 안좋은지는 모르겠지만 여튼 try ~ catch 로 감싸는 예제를 만들어야 한다면 저런 형태가 될 듯.
runCatching을 사용해 보자 0B
internal class RunCatchingService {
private val log = KotlinLogging.logger { }
.....
// throw
fun get0B() : Int {
val textNumber = TextNumber()
return runCatching {
textNumber.getThrow()
}.map {
it.toInt()
}.getOrThrow()
}
.....
try ~ catch 없이 runCatching내에서 실행이 이루어지고 .map으로 다시 Int Type으로 변경 후 반환한다.
( xxxx.map {} 은 보여주기 위함. runCatching내에서 이루어져도 무관 )
실행해보자
Test :
internal class RunCatchingTest() : StringSpec() {
private val log = KotlinLogging.logger { }
init {
....
"runCatching 0B RuntimeException 발생 그대로 throw" {
val sut = RunCatchingService()
shouldThrow<RuntimeException> {
sut.get0B()
}
}
....
RuntimeException이 그대로 반환된다.
근데 어떤 오류던간에 그냥 NumberFormatException 를 throw 하고 싶은 마음의 변화가 생겼다.
....
fun get1B() : Int {
val textNumber = TextNumber()
return runCatching {
textNumber.getThrow()
}.map {
it.toInt()
}.onFailure {
throw NumberFormatException()
}.getOrThrow()
}
....
runCatching구문내 예외가 있을 경우 onFailure가 실행되니 여기서 NumberFormatException()으로 throw 처리 한다.
Test:
....
"runCatching 1B RuntimeException 발생을 NumberFormatException으로 onFailure에서 변경. getOrThrow" {
val sut = RunCatchingService()
shouldThrow<NumberFormatException> {
sut.get1B()
}
}
....
이제 정상적으로 처리해보자.
....
fun get2B() : Int {
val textNumber = TextNumber()
return runCatching {
textNumber.getStringNumber()
}.map {
it.toInt()
}.onFailure {
throw NumberFormatException()
}.getOrThrow()
}
....
Test:
....
"runCatching 2B 정상적으로 1000 반환후 타입변환" {
val sut = RunCatchingService()
val num = sut.get2B()
num shouldBe 1000
}
....
대충 확인용으로 보는 코드.
Kotlin :
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/run-catching.html