테스트 실습 - 계산기 테스트

✒️ 2025-07-24 18:08 내용 수정


계산기 클래스

  1. Spring 프로젝트에서 StringCalculator 클래스를 생성한다.
  2. String을 입력 값으로 받고, String 내의 숫자들을 더하는 add() 메서드를 작성한다.
  3. add() 메서드는 다음과 같은 테스트를 통과해야 한다.
    • 빈 문자열이 들어오면 0을 반환한다.
    • 쉼표, 콜론, 커스텀 구분자로 구분된 숫자들을 더한다.
    • 음수가 들어오면 예외 처리를 한다.
    • 1000 이상의 숫자는 무시하고 계산한다.
  4. 각 조건별로 로직을 작성하고, 다음 조건에 맞게 조금씩 수정한다.
    • 다음 조건 테스트를 진행하고 이전 테스트도 통과하는지 확인한다.
package com.example.test.calc;  
  
import java.util.ArrayList;  
import java.util.List;  
  
public class StringCalculator {  
	public int add(String input) {  
		// ... 로직 작성
	}   
}

테스트 진행

테스트 클래스 생성

spring_test_calc 1.png

spring_test_calc 2.png

spring_test_calc 3.png

package com.example.test.calc;  
  
import org.junit.jupiter.api.BeforeEach;  
import org.junit.jupiter.api.DisplayName;  
import org.junit.jupiter.api.Test;  
  
class StringCalculatorTest {  
	private StringCalculator calculator;  
	
	private boolean isRightResult(int result, int expected) {  
		return result == expected;  
	}
	
	@BeforeEach  
	void setUp() {  
		calculator = new StringCalculator();  
	}  
}

1. 빈 문자 처리

package com.example.test.calc;  
  
import org.junit.jupiter.api.BeforeEach;  
import org.junit.jupiter.api.DisplayName;  
import org.junit.jupiter.api.Test;  
  
class StringCalculatorTest {  
	private StringCalculator calculator;  
	private boolean isRightResult(int result, int expected) {  
		return result == expected;  
	}
	
	@BeforeEach  
	void setUp() {  
		calculator = new StringCalculator();  
	}  
	
	@Test  
	@DisplayName("빈 문자열 입력 시 0을 반환")  
	void emptyStringReturnsZero() {  
		System.out.println(calculator.add(""));  
	}  
}
public class StringCalculator {  
	public int add(String input) {  
		if (input == null || input.isEmpty())
			return 0;  
	}  
}

2. 쉼표, 콜론, 커스텀 구분자 처리

  1. 쉼표, 콜론 구분자 처리
@Test  
@DisplayName("쉼표 구분자로 숫자를 더한다")  
void addNumbersWithComma() {  
	String input = "1,2,3";  
	int result = calculator.add(input);  
	System.out.println(isRightResult(result, 6));  
	
	String input2 = "1, 2, 3";  
	int result2 = calculator.add(input2);  
	System.out.println(isRightResult(result2, 6));  
}  
  
@Test  
@DisplayName("콜론 구분자로 숫자를 더한다")  
void addNumbersWithColon() {  
	String input = "1:2:3";  
	int result = calculator.add(input);  
	System.out.println(isRightResult(result, 6));  
}  
  
@Test  
@DisplayName("쉼표와 콜론을 혼용할 수 있다")  
void addNumbersWithMixedDelimiters() {  
	String input = "1,2:3";  
	int result = calculator.add(input);  
	System.out.println(isRightResult(result, 6));  
}
public class StringCalculator {  
	public int add(String input) {  
		int result = 0;
		String[] splitedInput = input.split(",|:");
	    
		for (String str : splitedInput) {  
			if (str.isEmpty()) continue;
			str = str.trim();  
		
			int num = Integer.parseInt(str);  
			result += num;
		}
		return result;
	}
}
  1. 커스텀 구분자
@Test  
@DisplayName("커스텀 구분자를 지정할 수 있다")  
void customDelimiter() {  
	String input = "//;\\n1;2;3";  
	int result = calculator.add(input);  
	System.out.println(isRightResult(result, 6));  
}  
  
@Test  
@DisplayName("커스텀 구분자가 여러 글자일 수 있다")  
void multiCharacterCustomDelimiter() {  
	String input = "//[***]\\n1***2***3";  
	int result = calculator.add(input);  
	System.out.println(isRightResult(result, 6));  
}
public class StringCalculator {  
	public int add(String input) {  
		int result = 0;
		// 숫자 제외 regex
		String[] splitedInput = input.split("\\D");
	    
		for (String str : splitedInput) {  
			if (str.isEmpty()) continue;
			str = str.trim();  
		
			int num = Integer.parseInt(str);  
			result += num;
		}
		return result;
	}
}

3. 음수 처리

@Test  
@DisplayName("음수 입력 시 예외가 발생한다")  
void negativeNumberThrowsException() {  
	System.out.println(calculator.add("4:-1:3"));  
}  

@Test  
@DisplayName("음수가 여러 개일 경우 모두 표시한다")  
void multipleNegativeNumbersInExceptionMessage() {  
	System.out.println(calculator.add("-1:-2:1"));  
} 
public class StringCalculator {  
	public int add(String input) {  
		int result = 0;  
		List<String> negatives = new ArrayList<>();  
		String[] splitedInput = input.split("[^\\d-]+");  
		
		for (String str : splitedInput) {  
			if (str.isEmpty()) continue;  
			str = str.trim();  
			
			int num = Integer.parseInt(str);  
			if (num < 0) {  
				negatives.add(str);  
				continue;  
			}  
			result += num;
		}  
		
		if (!negatives.isEmpty()) {  
			assertThatThronwBy(negatives.toString());  
		}  
		
		return result;  
	}  
	
	class NegativeIntegerException extends ArithmeticException {  
		public NegativeIntegerException(String message) {  
			super("음수는 입력할 수 없습니다. \n 음수 목록 : " + message);  
		}  
	}  
	
	private void assertThatThronwBy(String target) {  
		throw new NegativeIntegerException(target);  
	}  
}

4. 1000 이상 숫자 처리

@Test  
@DisplayName("1000을 초과하는 숫자는 무시한다")  
void ignoreNumbersGreaterThan1000() {  
	System.out.println(calculator.add("2,1001,6"));  
}  
public class StringCalculator {  
	public int add(String input) {  
		int result = 0;  
		List<String> negatives = new ArrayList<>();  
		String[] splitedInput = input.split("[^\\d-]+");  
		
		for (String str : splitedInput) {  
			if (str.isEmpty()) continue;  
			str = str.trim();  
			
			int num = Integer.parseInt(str);  
			if (num < 0) {  
				negatives.add(str);  
				continue;  
			}  
			result += (num < 1000) ? num : 0;  
		}  
		
		if (!negatives.isEmpty()) {  
			assertThatThronwBy(negatives.toString());  
		}  
		
		return result;  
	}  
	
	class NegativeIntegerException extends ArithmeticException {  
		public NegativeIntegerException(String message) {  
			super("음수는 입력할 수 없습니다. \n 음수 목록 : " + message);  
		}  
	}  
	
	private void assertThatThronwBy(String target) {  
		throw new NegativeIntegerException(target);  
	}  
}

최종 코드

package com.example.test.calc;  
  
import java.util.ArrayList;  
import java.util.List;  
  
public class StringCalculator {  
	public int add(String input) {  
		int result = 0;  
		List<String> negatives = new ArrayList<>();  
		String[] splitedInput = input.split("[^\\d-]+");  
		
		for (String str : splitedInput) {  
			if (str.isEmpty()) continue;  
			str = str.trim();  
			
			int num = Integer.parseInt(str);  
			if (num < 0) {  
				negatives.add(str);  
				continue;  
			}  
			result += (num < 1000) ? num : 0;  
		}  
		
		if (!negatives.isEmpty()) {  
			assertThatThronwBy(negatives.toString());  
		}  
		
		return result;  
	}  
	
	class NegativeIntegerException extends ArithmeticException {  
		public NegativeIntegerException(String message) {  
			super("음수는 입력할 수 없습니다. \n 음수 목록 : " + message);  
		}  
	}  
	
	private void assertThatThronwBy(String target) {  
		throw new NegativeIntegerException(target);  
	}  
}
package com.example.test.calc;  
  
import org.junit.jupiter.api.BeforeEach;  
import org.junit.jupiter.api.DisplayName;  
import org.junit.jupiter.api.Test;  
  
class StringCalculatorTest {  
	private StringCalculator calculator;  
  
	@BeforeEach  
	void setUp() {  
		calculator = new StringCalculator();  
	}  
	
	@Test  
	@DisplayName("빈 문자열 입력 시 0을 반환")  
	void emptyStringReturnsZero() {  
		System.out.println(calculator.add(""));  
	}  
	
	@Test  
	@DisplayName("쉼표 구분자로 숫자를 더한다")  
	void addNumbersWithComma() {  
		System.out.println(calculator.add("1,2,3"));  
		System.out.println(calculator.add("1, 2, 3"));  
	}  
	
	@Test  
	@DisplayName("콜론 구분자로 숫자를 더한다")  
	void addNumbersWithColon() {  
		System.out.println(calculator.add("1:2:3"));  
	}  
	
	@Test  
	@DisplayName("쉼표와 콜론을 혼용할 수 있다")  
	void addNumbersWithMixedDelimiters() {  
		System.out.println(calculator.add("1,2:3"));  
	}  
	
	@Test  
	@DisplayName("커스텀 구분자를 지정할 수 있다")  
	void customDelimiter() {  
		System.out.println(calculator.add("//;\\n1;2;3"));  
	}  
	
	@Test  
	@DisplayName("커스텀 구분자가 여러 글자일 수 있다")  
	void multiCharacterCustomDelimiter() {  
		System.out.println(calculator.add("//[***]\\n1***2***3"));  
	}  
	
	@Test  
	@DisplayName("음수 입력 시 예외가 발생한다")  
	void negativeNumberThrowsException() {  
		System.out.println(calculator.add("4:-1:3"));  
	}  
	
	@Test  
	@DisplayName("음수가 여러 개일 경우 모두 표시한다")  
	void multipleNegativeNumbersInExceptionMessage() {  
		System.out.println(calculator.add("-1:-2:1"));  
	}  
	
	@Test  
	@DisplayName("1000을 초과하는 숫자는 무시한다")  
	void ignoreNumbersGreaterThan1000() {  
		System.out.println(calculator.add("2,1001,6"));  
	}  
  
}