자바 단위 테스팅 프레임워크
JUnit5 - Java 진영에서 가장 많이 사용하는 테스팅 프레임워크 중에 하나
AssertJ - 테스트 코드 가독성을 높여주는 자바 라이브러리
테스트 코드를 작성하는 이유?
1. 문서화 역활
2. 코드에 결함을 발견한기 위함
3. 리팩토링 시 안정성 확보
4. 테스트 하기 쉬운 코드를 작성하다 보면 더 낮은 결합도를 가진 설계를 얻을 수 있음
TDD
1. Test Driven Development (테스트 주도 개발)
2. 프로덕션 코드보다 테스트 코드를 먼저 작성하는 개발 방법
3.TFD(Test First Development) + 리팩토링
4.기능 동작을 검증 ( 메소드 단위 ) BDD
1.Behavior Driven Development (행위 주도 개발)
2.시나리오 기반으로 테스트 코드를 작성하는 개발 방법
3.하나의 시나리오는 Given, When, Then 구조를 가짐
보통 TDD, BDD 를 혼용해서 사용한다.
실습1) 비밀번호 유효성 검증기
요구사항
1.비밀번호는 최소 8자 이상 12자 이하여야 한다.
2.비밀번호가 8자 미만 또는 12자 초과인 경우 IllegalArgumentException 예외를 발생시킨다.
3.경게조건에 대한 테스트 코드를 작성해야 한다.
build.gradle에 의존성 Assertj 3.23.1 추가 해준다
main 과 test 의 패키지 경로를 같이 해준다.
Display Name Annotation을 통해서 해당 테스트 코드의 의도를 나태내 준다.
1 - PassWordValidator 클래스: 비밀번호 유효성 검사를 한다.
2 - @DisplayName 어노테이션 : JUnit 테스트 메소드에 설명을 제공. 테스트 결과 보고소에서 테스트케이스가 어떤 동작을 검사하는지 이해하기 쉽도록 도와준다.
3 - @Test 어노테이션 : 테스트 메소드를 정의한다. validatePasswordTest 메소드에서 주어진 비밀번호가 8자 이상 12자 이하이면 예외가 발생하지 않아야 한다는 것을 테스트 한다.
4 - assertThatCode : AssertJ 라이브러리의 메소드로 , 주어진 코드 블록을 실행하고 예외가 발생하지 않는지 확인한다.
첫 번째 테스트에서는 주어진 비밀번호가 8자 이상 12자 이하일 떄 예외가 발생하지 않아야한다.
5 - @parameterizedTest 어노테이션과 @ValueSource 어노테이션 : 여러 입력 값에 대한 테스트를 수행한다.
두 번째 테스트 메소드인 validatePasswordTest2 에서는 비밀번호가 8자 미만 또는 12자 초과인 경우 예외가 발생한다.
6 - assertThatCode (두 번째 테스트 메소드에서 다시 사용) : 이 메소드를 사용하여 주어진 비밀번호가 조건에 충족하지 않을 때 예외가 발생하는지 확인한다. isInstanceOf 메소드는 발생한 예외가 IllegalArgumentException 클래스의 인스턴스인지 확인하고 hasMessage 메소드는 예외 메시지가 "비밀번호는 최소 8자 이상 12자 이하여야 한다." 와 일치하는지 확인한다.
1 - WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE : 클래스 내에서 사용 되는 예외 메시지를 정의한 상수다.
이 메시지는 비밀번호의 길이가 조건을 충족하지 않을 떄 예외를 발생시킬 때 사용된다.
2 - validate 메소드 : 이 메소드는 비밀번호를 인자로 받아서 비밀번호의 유효성을 검사하는 역확을 한다.
구체적으로 말하면
- 비밀번호 길이 ( 'length') 가 8미만이거나 12초과인 경우 IllegalArgumentException 예외를 발생시킨다 예외 메시지로는 위에 정의한 WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE 가 사용된다.
-그 외의 경우 예외를 발생시키지 않고 메소드는 정상적으로 종료된다.
org.example.PasswordGenerator 인터페이스를 구현하고 , 다양한 문자 규칙과 제한 조건을 사용하여 비밀번호를 생성한다
1 - PasswordGenerator 클래스 : Passay 라이브러리를 사용하여 비밀번호를 생성하기 위해 PasswordGenerator 클래스를 사용
2 - 문자 규칙 ( CharacterRule) : 다양한 문자 규칙이 정의되어 있다. 예를 들어 소문자, 대문자, 숫자, 특수문자를 나타내는 문자 데이터를 정의하고 각각에 대한 규칙을 생성한다.
3 - generatePassword 메소드: 이 메소드는 실제 비밀번호를 생성한다 비밀번호의 길이는 0에서 12 사이의 임의의 값으로 설정된다. 그런 다음 소문자, 대문자, 숫자 및 특수 문자에 대한 규칙을 적용하여 비밀번호를 생성하고 반환한다.
4 - 특수 문자: ALLOWED_SPL_CHARACTERS 상수를 통해 허용된 특수 문자를 정의하고, ERROR_CODE 상수를 사용하여 특수 문자 관련 오류 코드를 정의한다.
사용자의 비밀번호를 초기화 하고 저장하는데 사용하고 비밀번호 생성에 PasswordGenerator 를 사용한다.
1 - User 클래스 : 사용자의 비밀번호를 나타내는 클래스입니다 . 비밀번호는 password 필드에 저장된다.
2 - intiPassword 메소드 : 이 메소드는 비밀번호 생성기(PasswordGenerator)를 인자로 받아서 사용자의 비밀번호를 초기화한다 먼저 passwordGenerator를 사용하여 무작위 비밀번호를 생성하고, 그런 다음 생성된 비밀번호의 길이를 검사 한다. 주석에 따라 비밀번호는 최소 8자 이상 12자 이하여야 한다. 이 조건을 만족하는 경우에만 비밀번호를 저장한다.
3 - getPassword 메소드: 저장된 비밀번호를 반환한다.
이 클래스는 주어진 PasswordGenerator를 통해 무작위 비밀번호를 생성하고, 생성된 비밀번호가 조건에 부합하는 경우에만 저장 그런 다음 getPassword 메소드를 사용하여 저장된 비밀번호를 얻을 수 있다 이렇게 구현된 클래스는 사용자 비밀번호 초기화 및 조회를 수행하는 데 사용된다.
User 클래스의 테스트 코드로 , 사용자의 비밀번호 초기화와 관련된 두 가지 케이스를 포함한다.
이 코드는 JUnit과 AssertJ 라이브러리를 사용하여 테스트를 정의하고 실행한다.
1 - 패스워드를 초기화한다 테스트 케이스:
@DisplayName 어노테이션은 테스트 케이스에 설명을 부여한다.
User 객체를 생성
user.initPassword(() -> "abcdefgh");를 호출하여 비밀번호를 초기화 이 부분에서 람다 표현식을 사용하여 무작위 비밀번호를 생성하는 것이 아니라, 고정된 문자열 "abcdefgh"를 사용하고 있다 이것은 테스트를 위한 목적으로 고정된 비밀번호를 설정하는 것
assertThat(user.getPassword()).isNotNull();를 사용하여 비밀번호가 초기화되었는지 확인합니다. 즉, 비밀번호가 null이 아닌지 검사
2 - 패스워드가 요구사항에 부합하지 않아 초기화가 되지 않는다 테스트 케이스:
@DisplayName 어노테이션을 사용하여 테스트 케이스에 설명을 부여합니다.
User 객체를 생성합니다.
user.initPassword(() -> "ab");를 호출하여 비밀번호를 초기화합니다. 이번에는 "ab"라는 짧은 문자열을 사용하여 비밀번호 초기화를 시도하고 있습니다.
assertThat(user.getPassword()).isNull();를 사용하여 비밀번호가 초기화되지 않았음을 확인합니다. initPassword 메소드 내에서 비밀번호 길이가 요구사항에 맞지 않으므로 비밀번호가 null이 되어야 합니다.
이러한 테스트 코드를 사용하면 User 클래스의 initPassword 메소드가 주어진 조건에 따라 비밀번호를 초기화하는지 확인할 수 있다. 첫 번째 테스트는 조건을 충족하므로 비밀번호가 초기화된다. 두 번째 테스트는 조건을 충족하지 않으므로 초기화되지 않는다.
1 - @FunctionalInterface: 이 어노테이션은 인터페이스가 함수형 인터페이스임을 나타낸다. 함수형 인터페이스는 하나의 추상 메소드만을 가지며, 람다식 또는 메소드 참조를 통해 함수를 표현할 수 있다..
2 - PasswordGenerator 인터페이스: 이 인터페이스는 단일 메소드 generatePassword를 선언하고 있다. 이 메소드는 비밀번호를 생성하고 문자열로 반환하는 역활을 한다.
예를 들어, RandomPasswordGenerator 클래스는 PasswordGenerator 인터페이스를 구현하고, generatePassword 메소드를 오버라이드하여 무작위 비밀번호를 생성하도록 구현할 수 있다 이렇게 함으로써 다양한 방식으로 비밀번호 생성기를 구현할 수 있고, 이러한 구현을 PasswordGenerator 인터페이스를 준수하도록 유지할 수 있다.
함수형 인터페이스와 람다식은 Java 8부터 도입되었으며, 함수형 프로그래밍의 개념을 Java에 손쉽게 통합하도록 도와준다. 이러한 인터페이스를 사용하면 코드를 간결하게 작성하고, 다양한 기능을 구현하거나 전달할 수 있음.
PasswordGenerator 인터페이스 구현: CorrectFixedPasswordGenerator 클래스는 PasswordGenerator 인터페이스를 구현한다 이것은 generatePassword 메소드를 반드시 구현해야 함을 의미함
generatePassword 메소드: 이 메소드는 항상 "abcdefgh"라는 고정된 문자열을 반환. 즉, 이 비밀번호 생성기는 항상 동일한 비밀번호를 생성
CorrectFixedPasswordGenerator 클래스는 주어진 상황에 대비한 테스트나 특정 시나리오에서 일관된 비밀번호를 필요로 할 때 사용할 수 있다. 예를 들어, 특정 테스트 케이스에서 예상되는 비밀번호를 고정된 값으로 설정하거나, 개발 중에 특정 기능을 검사하는 데 사용할 수 있다.
비밀번호 생성기가 실제로 무작위 또는 보안 강화된 비밀번호를 생성하는 경우에는 실제로 랜덤한 값을 반환하는 다른 클래스를 사용하는 것이 좋다.
1 - PasswordGenerator 인터페이스 구현: WrongFixedPasswordGenerator 클래스는 PasswordGenerator 인터페이스를 구현. 이것은 generatePassword 메소드를 반드시 구현해야 함을 의미한다.
2 - generatePassword 메소드: 이 메소드는 항상 "ab"라는 고정된 문자열을 반환. 즉, 이 비밀번호 생성기는 항상 동일한 2글자의 비밀번호 "ab"를 생성한다.
WrongFixedPasswordGenerator 클래스는 주로 특정 상황에서 예상치 않은 동작을 시뮬레이션하기 위해 사용. 예를 들어 특정 테스트 케이스에서 유효하지 않은 비밀번호를 생성하거나 특정 오류 조건을 테스트하는 데 사용할 수 있다. 이러한 예는 코드가 예상치 않은 입력에 대해 어떻게 동작하는지 확인하는 데 유용
'JAVA > 객체지향' 카테고리의 다른 글
객체지향 프로그래밍 실습(3) (1) | 2023.10.31 |
---|---|
객체지향 프로그래밍(2) (0) | 2023.10.30 |
객체지향 프로그래밍(1) (1) | 2023.10.29 |
객체지향 개념정리 (1) | 2023.10.27 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!