PHpullh
학습 라이브러리/Kotlin/테스트 더블 (Stub, Mock, Spy)

KOTLIN · 테스트

테스트 더블 (Stub, Mock, Spy)

테스트 더블의 종류와 적절한 사용 시점을 이해합니다. Stub은 값 반환, Mock은 호출 검증, Spy는 부분 모킹입니다.

테스트중급test-doublestubmockspyverification

핵심 설명

테스트 더블의 종류와 적절한 사용 시점을 이해합니다. Stub은 값 반환, Mock은 호출 검증, Spy는 부분 모킹입니다.

Kotlin code

interface NotificationService {
    fun send(to: String, message: String): Boolean
    fun getHistory(): List<String>
}

// Stub: 미리 정의된 값 반환
class StubNotification : NotificationService {
    override fun send(to: String, message: String) = true
    override fun getHistory() = listOf("msg1", "msg2")
}

// Mock: 호출 검증
class MockNotification : NotificationService {
    val sendCalls = mutableListOf<Pair<String, String>>()
    var sendResult = true

    override fun send(to: String, message: String): Boolean {
        sendCalls.add(to to message)
        return sendResult
    }
    override fun getHistory() = emptyList<String>()

    fun verifySendCalledWith(to: String, message: String) {
        assert(sendCalls.any { it == to to message }) {
            "send($to, $message) 호출되지 않음. 실제: $sendCalls"
        }
    }
    fun verifySendCallCount(count: Int) {
        assert(sendCalls.size == count) {
            "send 호출 횟수: ${sendCalls.size}, 기대: $count"
        }
    }
}

fun main() {
    // Stub 사용: 반환값만 중요
    val stub = StubNotification()
    assert(stub.send("user", "hello"))
    println("✓ Stub 테스트 통과")

    // Mock 사용: 호출 검증
    val mock = MockNotification()
    mock.send("admin@test.com", "알림")
    mock.send("user@test.com", "환영")
    mock.verifySendCalledWith("admin@test.com", "알림")
    mock.verifySendCallCount(2)
    println("✓ Mock 테스트 통과")
}

학습 팁

상태 검증에는 Stub, 행위 검증에는 Mock을 사용하세요. Mock을 남용하면 테스트가 구현에 결합됩니다.

주의할 점

모든 의존성을 Mock으로 만들면 테스트가 깨지기 쉽습니다. 인터페이스 경계에서만 Mock을 사용하고, 값 객체는 실제 인스턴스를 쓰세요.

자주 묻는 질문

테스트 더블 (Stub, Mock, Spy)란 무엇인가요?

테스트 더블의 종류와 적절한 사용 시점을 이해합니다. Stub은 값 반환, Mock은 호출 검증, Spy는 부분 모킹입니다.

테스트 더블 (Stub, Mock, Spy) 학습 시 주의할 점은 무엇인가요?

모든 의존성을 Mock으로 만들면 테스트가 깨지기 쉽습니다. 인터페이스 경계에서만 Mock을 사용하고, 값 객체는 실제 인스턴스를 쓰세요.