[JUnit] Bad Test
- JUnit
- 2020. 8. 20.
이번글에서는 prime number 예제를 통해 좋은 test code를 작성하는 방법에 대해 알아보도록 하겠습니다.
1. Check Prime Number
먼저 아래와 같이 Prime Number 인지 아닌지를 확인하는 NumberValidator 클래스가 있다고 가정해보겠습니다.
NumberValidator
public class NumberValidator {
public boolean isItPrime(int number) {
int maxDivisor = (int)Math.sqrt(number);
for(int i=2;i<=maxDivisor;i++) {
if(number % i==0)
return false;
}
return true;
}
}
위의 isItPrime 메서드는 input number를 적절히 계산해 prime number 일 경우 true를 그렇지 않을 경우에는 false를 return 하도록 설계되었습니다.
위의 business logic을 테스트하는 test code는 아래와 같습니다.
NumberValidatorTests
public class NumberValidatorTests {
@Test
public void checkPrimeNumber(){
Integer numbers[] = {1, 15, 23, 25, 60, 61, 63, 79, 207};
NumberValidator validator = new NumberValidator();
for(int i=0; i< numbers.length; i++){
boolean isPrime = true;
int maxDivisor = (int) Math.sqrt(numbers[i]);
for(int counter = 2; counter <= maxDivisor; counter++){
if(numbers[i] % counter ==0){
isPrime = false;
}
}
assertEquals(isPrime, validator.isItPrime(numbers[i]));
}
}
}
위의 test code는 먼저 numbers 배열에 담긴 숫자들 중 prime number인 숫자들과 prime number가 아닌 숫자들을 구분합니다.
다음으로 prime number인 숫자를 isItPrime 메서드에 넣었을때 결과값으로 true를 return 하는지와 prime number가 아닌 숫자를 isItPrime 메서드에 넣었을때 결과값으로 false를 return 하는지를 test 합니다.
테스트 해보겠습니다.
짠 😎~ 위와 같이 test가 통과했습니다.
만약 뭔가 이상한걸 눈치채셨다면, 이미 당신은 고수.. 입니다.
그렇습니다. 위의 test code는 뭔가 이상합니다. 다시한번 아래의 빨간색 부분을 살펴보겠습니다.
눈치 채셨나요? 맞습니다. 현재 위에서 작성한 test code는 지나치게 business logic을 반복하고 있습니다. 따라서 위의 test를 수행할 경우 동일한 logic을 2번 수행하는 것과 다름없는 것 입니다.
따라서 위와 같은 bad test를 refactoring 할 필요가 있습니다.
2. Refactoring
test code에서는 위와 같은 logic을 수행할 필요가 전혀 없습니다. 단지 우리는 어떠한 값을 던져 주었을때, 원하는 결과값을 return 하는가? 만 정적으로 확인해보면 됩니다. 따라서 우리는 다음과 같이 test code를 변경할 수 있습니다.
NumberValidatorTests
public class NumberValidatorTests {
@Test
public void checkPrimeNumbers()
{
Integer numbers[] = {1,23,61,79};
NumberValidator validator = new NumberValidator();
for (int i = 0; i < numbers.length; i++) {
assertEquals(true, validator.isItPrime(numbers[i]));
}
}
@Test
public void checkNonPrimeNumbers()
{
Integer numbers[] = {15,25,60,63,207};
NumberValidator validator = new NumberValidator();
for (int i = 0; i < numbers.length; i++) {
assertEquals(false, validator.isItPrime(numbers[i]));
}
}
}
기존 1개의 test가 2개의 test로 분리되었습니다.
해석해보면 checkPrimeNumbers는 prime number를 isItPrime 메서드의 input으로 넣을 경우 true 값을 return 하는지 확인합니다. 반대로 checkNonPrimeNumbers는 non prime number를 isItPrime 메서드의 input으로 넣을 경우 false를 return 하는지 확인합니다.
테스트 해보겠습니다.
위와 같이 테스트가 통과했습니다. 이로써 우리는 더이상 test code 내부에서 business logic을 작성하지 않게 되었습니다. 👏👏👏
참고 자료 : https://www.udemy.com/course/practical-test-driven-development-for-java-programmers/
추천서적
파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음
'JUnit' 카테고리의 다른 글
[JUnit] MockMvc (0) | 2020.08.20 |
---|---|
[JUnit] Spy (0) | 2020.08.20 |
[JUnit] Mock & Mockito -2 (0) | 2020.08.20 |
[JUnit] Mock & Mockito -1 (0) | 2020.08.20 |
[JUnit] Stub (0) | 2020.08.20 |