본문 바로가기

Java

TDD방법론 - 암호검사기4(WEAK CASE)

테스트 3:

 -길이가 8글자 이상인 조건만 충족

 -숫자 포함 조건만 충족

 -대문자 포함 조건만 충족

+ 아무 조건도 충족하지 못한 경우

 

    @Test
    @DisplayName("길이가 8자 이상인 조건만 충족")
    void weak_1() {
        assertStrength("qwertasdf", PasswordStrength.WEAK);
    }
 
    @Test
    @DisplayName("숫자 포함 조건만 충족")
    void weak_2() {
        assertStrength("1234", PasswordStrength.WEAK);
    }
 
    @Test
    @DisplayName("대문자 포함 조건만 충족")
    void weak_3() {
        assertStrength("QWERTY", PasswordStrength.WEAK);
    }
    
    @Test
    @DisplayName("아무 조건도 충족하지 않은 경우")
    void weak_4() {
        assertStrength("abc", PasswordStrength.WEAK);
    }
 
cs

테스트 코드

 

public class PasswordStrengthMeter {
    
        boolean lengthEnough = s.length() >= 8;
        boolean containsNum = checkNumber(s);
        boolean containsUpp = checkUppercase(s);
 
        if(lengthEnough && !containsNum && !containsUpp)
            return PasswordStrength.WEAK;
        if(!lengthEnough && containsNum && !containsUpp)
            return PasswordStrength.WEAK;
        if(!lengthEnough && !containsNum && containsUpp)
            return PasswordStrength.WEAK;
        if(!lengthEnough && !containsNum && !containsUpp)
            return PasswordStrength.WEAK;
        if (!lengthEnough)
            return PasswordStrength.NORMAL;
        if (!containsNum)
            return PasswordStrength.NORMAL;
        if (!containsUpp)
            return PasswordStrength.NORMAL;
        
        return PasswordStrength.STRONG;
    }
 
cs

테스트 로직

 

로직은 NORMAL 테스트에서 만들어둔 boolean값들을 취사선택해서 쓴다.

작성과정은 생략되었지만 TDD의 핵심은 매 단위테스트마다 로직 구현전에

테스트코드를 실행하고, 오류발생시 오류메시지를 토대로 테스트로직을 작성하는것이다. 

 

 

테스트 4: 입력값이 없는 경우

사실 이러한 예외상황은 TDD과정에서 최우선적으로 고려해야한다. 

다른 암호검증로직에 null값이 전달되면 프로그램이 중지하고 바로 NullPointerException이 발생하기 때문이다.

 

   @Test
    @DisplayName("입력값이 null일 경우")
    void inputNull() {
        assertStrength(null, PasswordStrength.INVALID);
    }
 
cs

 

 

null을 입력받을 경우 NullPointerException이 발생한다.

예외없이 동작하게 만들기 위해서 null을 입력받는 경우의 암호등급도 할당한다.

 

public enum PasswordStrength {
    STRONG,
    NORMAL,
    WEAK,
    INVALID
}
 
cs

null값을 받았을때 반환하는 암호등급을 INVALID로 설정

 

    @Test
    @DisplayName("입력값이 null일 경우")
    void inputNull() {
        assertStrength(null, PasswordStrength.INVALID);
    }
 
cs

테스트코드

 

 public PasswordStrength meter(String s) {
        if (s == null)
            return PasswordStrength.INVALID;
 
        boolean lengthEnough = s.length() >= 8;
        boolean containsNum = checkNumber(s);
        boolean containsUpp = checkUppercase(s);
 
        if(lengthEnough && !containsNum && !containsUpp)
            return PasswordStrength.WEAK;
        if(!lengthEnough && containsNum && !containsUpp)
            return PasswordStrength.WEAK;
        if(!lengthEnough && !containsNum && containsUpp)
            return PasswordStrength.WEAK;
        if (!lengthEnough)
            return PasswordStrength.NORMAL;
        if (!containsNum)
            return PasswordStrength.NORMAL;
        if (!containsUpp)
            return PasswordStrength.NORMAL;
        return PasswordStrength.STRONG;
    }
 
cs

테스트로직

 

null체크 구문은(if s == null) 메소드 최상단에 위치해야한다.

if절들을 모아놨다고 밑쪽으로 옮기면 

boolean lengthEnough = s.length() >= 8;

여기서 바로 NullPointerException이 뜨면서 프로그램이 멈출것이다.

 

    @Test
    @DisplayName("입력값이 공백일 경우")
    void inputBlank() {
        assertStrength("", PasswordStrength.INVALID);
    }
 
cs

 

null값을 고려할때 항상 따라오는 공백값 조건도 고려한다.

(null과 공백은 엄연히 다른 입력값이므로)

 

if (s == null || s.isEmpty())
    return PasswordStrength.INVALID;

null, isEmpty 둘중 하나만 만족해도 INVALID를 반환하도록 if문을 수정한다.