본문 바로가기

Java

TDD방법론 - 암호검사기2(NORMAL CASE)

모든 규칙을 충족할 경우를 테스트했으니 이제 조건을 하나씩 빼면서 테스트를 한다.

 

- 길이가 8글자 이상

- 0~9사이의 숫자를 포함

- 대문자 포함

 

테스트2-1: 길이는 8글자 미만, 나머지 조건은 충족

 

public class PasswordStrengthMeterTest {
    @Test
    @DisplayName("모든 규칙을 충족하는 경우")
    void Strong() {
        PasswordStrengthMeter meter = new PasswordStrengthMeter();
        PasswordStrength result = meter.meter("12!@abAB");
        assertEquals(PasswordStrength.STRONG, result);
 
    }
 
    @Test
    @DisplayName("길이만 8자 미만이고 나머지 조건은 충족")
    void normal_1() {
        PasswordStrengthMeter meter = new PasswordStrengthMeter();
        PasswordStrength result = meter.meter("ab12!@A");
        assertEquals(PasswordStrength.NORMAL, result);
    }
}
 
cs

 

 

테스트코드 실행결과 당연히 오류가 뜬다.

public PasswordStrength meter(String s) {
    return PasswordStrength.STRONG;
}

meter()메소드는 어떤 값을 받던간에 STRONG만 반환하기 때문이다.

 

public PasswordStrength meter(String s) {
    return PasswordStrength.NORMAL;
}

 

새로 추가한 테스트를 통과시키는 가장 쉬운방법은 첫번째 케이스때처럼 반환값만 NORMAL로 나오게 수정하는것이다.

 

 

그러나 이번에는 STRONG을 필요로 하는 첫번째 케이스에서 오류가 발생한다.

 

이제 두 테스트 모두 통과시킬수 있는 코드를 작성한다.

 

public class PasswordStrengthMeter {
    public PasswordStrength meter(String s) {
        if (s.length() < 8) {
            return PasswordStrength.NORMAL;
        }
        return PasswordStrength.STRONG;
    }
}
 
cs

 

 

테스트2-2: 숫자는 미포함, 나머지조건은 충족

 

    @Test
    @DisplayName("숫자 미포함, 나머지 조건 충족")
    void normal_2() {
        PasswordStrengthMeter meter = new PasswordStrengthMeter();
        PasswordStrength result = meter.meter("qwerAS!@");
        assertEquals(PasswordStrength.NORMAL, result);
   }
cs

 

 

현재 meter메소드는 8자 미만은 전부 STRONG을 반환하기 때문에 당연히 에러가 발생한다. 

meter메소드에 숫자값을 판별하는 로직을 추가한다.

 

public class PasswordStrengthMeter {
    public PasswordStrength meter(String s) {
        if (s.length() < 8) {
            return PasswordStrength.NORMAL;
        }
        boolean containsNum = false;
        for (char c : s.toCharArray()) {
            if (c >= '0' && c <= '9') {
                containsNum = true;
                break;
            }
        }
        if(!containsNum)
            return PasswordStrength.NORMAL;
        return PasswordStrength.STRONG;
    }
}
 
cs

 

 

toCharArray메소드로 입력받은 문자열을 한글자씩 쪼개서 char타입 배열에 담은 뒤

반복문을 돌려 숫자값이 있는지 테스트한다.

char타입일때는 아스키코드로

0은 48, 1은 49, ..... 9는 57의 값을 갖기 때문에 대소비교가 가능하다.

 

앞으로 더 많은 케이스를 테스트해야 하기때문에 길어진 숫자판별로직은 별개의 메소드로 리팩토링한다.

 

public class PasswordStrengthMeter {
    public PasswordStrength meter(String s) {
        if (s.length() < 8) {
            return PasswordStrength.NORMAL;
        }
        boolean containsNum = checkNumber(s);
 
        if(!containsNum)
            return PasswordStrength.NORMAL;
        return PasswordStrength.STRONG;
    }
 
    private boolean checkNumber(String s) {
        for (char c : s.toCharArray()) {
            if (c >= '0' && c <= '9') {
                return true;
            }
        }
    return false;
    }
}
 
cs

 

테스트 2-3: 대문자 미포함, 나머지 조건 충족

 

    @Test
    @DisplayName("대문자 미포함, 나머지 조건 충족")
    void normal_3() {
        PasswordStrengthMeter meter = new PasswordStrengthMeter();
        PasswordStrength result = meter.meter("1q!2w@3e#");
        assertEquals(PasswordStrength.NORMAL, result);
    }
 
cs

 

public class PasswordStrengthMeter {
    public PasswordStrength meter(String s) {
        if (s.length() < 8) {
            return PasswordStrength.NORMAL;
        }
        boolean containsNum = checkNumber(s);
 
        if (!containsNum)
            return PasswordStrength.NORMAL;
        boolean containsUpp = checkUppercase(s);
        if (!containsUpp)
            return PasswordStrength.NORMAL;
        return PasswordStrength.STRONG;
    }
 
    private boolean checkNumber(String s) {
       //생략
    }
 
    private boolean checkUppercase(String s) {
        for (char c : s.toCharArray()) {
            if (Character.isUpperCase(c)) {
                return true;
            }
        }
        return false;
    }
}
 
cs

 

작성요령은 테스트2-2와 같다. toCharArray()로 문자열을 쪼갠 뒤

이번에는 isUpperCase()로 대문자를 판별한다.

 

NORMAL케이스까지 테스트 완료