728x90
사칙연산 계산기에 대한 테스트 코드 작성(순수한 kotlin 코드)
사칙 연산 코드(Calculator.kt)
class Calculator(
//private var _number: Int //생성자로 받아 이 값을 계속 업데이트 할 예정
var number: Int
) {
/*
val number: Int
get() = this.number
*/
fun add(operand: Int) {
this.number += operand
}
fun minus(operand: Int) {
this.number -= operand
}
fun multiply(operand: Int) {
this.number *= operand
}
fun divide(operand: Int) {
if (operand == 0)
throw IllegalArgumentException("0으로 나눌 수 없습니다.ㄴ")
this.number /= operand
}
}
Test 코드
class CalculatorTest {
/**
* 덧셈 테스트
*/
fun addTest() {
//given : 테스트 준비
val calculator = Calculator(5)
//when : 테스트 기능 호출
calculator.add(3)
//비교 방법1: data클래스 사용
/*
val expectedCalculator = Calculator(8)
if (calculator != expectedCalculator) {
throw IllegalStateException()
}
*/
//비교 방법2: private 키워드를 제거
//단 이방법은 number 값을 setter를 통해 변경할 수 있기 때문에
//then : 테스트 결
if(calculator.number != 8){
throw IllegalStateException()
}
}
fun minusTest() {
//given
val calculator = Calculator(5)
//when
calculator.minus(3)
//then
if(calculator.number != 2){
throw IllegalStateException()
}
}
fun multiplyTest() {
//given
val calculator = Calculator(5)
//when
calculator.multiply(3)
//then
if(calculator.number != 15){
throw IllegalStateException()
}
}
fun divideTest() {
//given
val calculator = Calculator(5)
//when
calculator.divide(2)
//then
if (calculator.number != 2) {
throw IllegalStateException()
}
}
fun divideExceptionTest() {
//given
val calculator = Calculator(5)
//when : IllegalArgumentException이 발생하기를 기대한다
try {
calculator.divide(0)
}catch (e: IllegalArgumentException){
if(e.message != "0으로 나눌 수 없습니다.")
throw IllegalStateException("메시지가 다릅니다.")
//테스트 성공
return
}catch (e: Exception){
throw IllegalStateException()
}
throw IllegalStateException("기대하는 예외가 발생하지 않았습니다.")
}
}
fun main() {
val calculatorTest = CalculatorTest()
calculatorTest.addTest()
calculatorTest.minusTest()
calculatorTest.multiplyTest()
calculatorTest.divideTest()
calculatorTest.divideExceptionTest()
}
- main에서 작성한 테스트 코드를 실행한다.
- 덧셈, 뺄셈, 곱셈, 나눗셈
- 테스트를 하기 위해서는 Calculator을 number를 가지고 와야 하는 데, 방법은 2가지가 있다.
- data 클래스로 만들어 equals 를 실행시키자 (if(calculator!= expectedResult)를 실행하면 내부적으로 equals 호출
- Calculator에서, number를 가지고 올 수 있는데 private 키워드를 제거하거나(값을 막 변경할 수 있는 단점이 있다), 원래 존재하던 number 프로퍼티를 _number 이름으로 변경하고, 불변 number를 추가하는 방법도 있다.(백킹 프로퍼티)
- 테스트 메소드는 크게 3단계로 구성된다(given, when, then)
- given : 테스트 대상을 만들어 준비하는 과정
- when: 실제 테스트하고 싶은 기능을 호출하는 과정
- then : 호출 이후 의도한 대로 결과가 나왔는지 확인하는 과정
- 나눗셈 같은 경우, 0으로 나누었을때 예외가 발생하는지와, 0으로 나누지 않았을 때 정상적으로 동작하는지를 테스트해야 한다.
- 정상적으로 동작했을 때 (divideTest)는 다른 테스트 코드와 같다.
- 정상적으로 동작하지 않고, 예외가 발생했는지를 테스트할 때는 try-catch 구문을 통해, 발생되는 예외를 잡고, 해당 부분에서 메시지 또한 같은지를 확인할 수 있다.(IllegalArgumentException이 발생하지 않을 경우 테스트가 정상적으로 동작하지 않음으로 다른 예외를 발생시킨다.)
수동으로 만든 테스트 단점
- 테스트 클래스가 많아지고, 메서드가 생길 때마다 메인 메서드에 수동으로 코드를 작성해 주어야 한다
- 메인 메서드가 커지고, 개별적 실행이 어렵다.
- 테스트가 실패할 경우 무엇을 기대하고, 어떤 값이 들어와 실패했는지 알려주지 않는다. 또한 예외를 던지거나, try-catch를 사용해야 하는 등 직접 구현해야 할 부분이 많다.
- 테스트 메서드 별로 공통적으로 처리해야 하는 기능이 있다면, 메서드 중복이 생기게 된다
이러한 단점을 극복하기 위해 테스트 프레임워크가 등장하였다(JUnit5)
728x90
'실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기' 카테고리의 다른 글
| Ch02. Java 서버를 Kotlin 서버로 리팩토링하자 - Domain 계층 리펙토링하기 (0) | 2022.11.01 |
|---|---|
| Ch01. 도서관리 애플리케이션 리팩토링 준비하기 - JUnit5으로 Spring Boot 테스트 하기 (0) | 2022.10.29 |
| Ch01. 도서관리 애플리케이션 리팩토링 준비하기 - JUnit5 사용하기 (0) | 2022.10.29 |
| Ch01. 도서관리 애플리케이션 리팩토링 준비하기 - 테스트 코드?! (0) | 2022.10.29 |
| Ch01. 도서관리 애플리케이션 리팩토링 준비하기 - 도서 관리 애플리케이션 이해하기 (0) | 2022.10.25 |