Dependency Injection 이 왜 필요한가요?? .. (2)

킹정인·2023년 5월 16일
1

Dependency injection

목록 보기
2/3

DI 에 대한 두번째 포스팅입니다.

첫번째 게시글은 아래를 링크로!
https://velog.io/@king-jungin/Dependency-Injection-%EA%B0%80-%EC%99%9C-%ED%95%84%EC%9A%94%ED%95%9C%EA%B0%80%EC%9A%94..-1

의존성 주입

예시

Testable

이전 포스팅에서 의존성 주입은 Tesable 한 코드를 작성할 수 있다고 했습니다.
과연 Testable 한 코드는 무엇일까요?

아래에 요구사항에 따른 코드가 있습니다.

요구사항

1. 랜덤한 숫자를 가진 랜덤박스가 있습니다.
2. 이 랜덤박스는 랜덤한 숫자가 90 이상인 경우에만 상품이 들어있습니다.

코드

object Goods

class RandomBox {
    private val score = Random(System.currentTimeMillis()).nextInt(100)

    fun unBoxing() = if (score >= 90) {
        Goods
    } else {
        null
    }
}

자! 이제 우리는 이 코드가 잘 동작하는지 확인하고 싶습니다.
그 중에 실제로 랜덤한 숫자 score90 이상이면 Goods 를 반환해 주는지 테스트하고 싶은데요.

여기서 문제가 있습니다.

score90 이상인 상황을 테스트하기 위해서는

  1. 디버깅을 통해 90 이상이 나올때까지 돌려본다😱

바람직하지 않습니다. 언제 나올줄 알고 돌려보나요...

  1. Random 로직을 주석 처리하고 score 에 정수 90을 넣어 재빌드한다.🤮

이 또한 바람직하지 않습니다.
물론 현재로선 간단하겠지만, 로직이 복잡해지면 주석 처리할 곳이 많아져 테스트가 심히 어려워집니다.

그렇다면 어떻게 해야할까요??

의존성 주입으로 해결이 가능합니다.

RandomInt.kt

interface RandomInt {
    operator fun invoke(): Int
}

class RandomIntImpl: RandomInt {
    override fun invoke() = Random(System.currentTimeMillis()).nextInt(100)
}

RandomBox2.kt

class RandomBox2(
    random: RandomInt
) {
    private val score = random()

    fun unBoxing() = if (score >= 90) {
        Goods
    } else {
        null
    }
}

Main.kt

fun main(args: Any) {
    val goods = RandomBox2(RandomIntImpl()).unBoxing()
    // ...
}

위 코드는 의존성 주입으로 구현된 코드입니다.

  • RandomInt 는 랜덤 정수를 반환하는 로직을 추상화한 interface 입니다.
  • 기존 랜덤 로직은 RandomIntImpl 에서 구현합니다.
  • RandomBox2 는 추상화된 RandomInt interface 를 주입받아 score 에 값을 할당합니다.

즉, 랜덤 정수를 추출하는 로직을 추상화하여 주입하고 있으므로 다양한 알고리즘의 랜덤 로직을 주입하여 사용할 수 있고, 테스트용 랜덤 로직을 작성하여 주입할 수도 있게 되었습니다.

아래는 score90 이상인 Case 테스트의 예시입니다.

RandomIntTestImpl

class RandomIntTestImpl: RandomInt {
    override fun invoke() = 90
}

main.kt

fun main(args: Any) {
    val goods = RandomBox2(RandomIntTestImpl()).unBoxing()
    // ...
}

RandomIntTestImpl 클래스가 정수 90 만을 반환도록 구현되어 있으므로, 이를 주입하여 Goods 가 반환되는지에 대한 테스트가 가능하게 되었습니다.

이를 응용하여 JunitMockito 등을 활용한 Unit Test 가 가능합니다.

--> 다음 포스팅에 계속..

profile
🕶안드로이드 개발자입니다! 🕶

0개의 댓글