์์๋ GDSC MJU์์ TDD ์คํฐ๋๋ฅผ ์์ํ์ฌ, ๋ค์ ์ฑ ์ ์ ๋ฆฌํ๋ ๋ธ๋ก๊ทธ ํฌ์คํ ์ ์งํํ๊ณ ์ ํ๋ค.
๐ TDD Chapter 1: TDD ๊ฐ๋ฐ ์ค๋น
๊ฐ๋จํ๊ธฐ ๋๋ฌธ์ build.gradle ์ค์ ๋ง ์์ฑํ๊ณ ๋์ด๊ฐ๋ค.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// junit ์ถ๊ฐ
testImplementation('org.junit.jupiter:junit-jupiter:5.5.0')
}
๐ TDD Chapter 2: TDD ์์
๐ TDD๋?
ํ ์คํธ๋?
๊ธฐ๋ฅ์ ์ฌ๋ฐ๋ฅด๊ฒ ๋์ํ๋์ง ๊ฒ์ฆํ๋ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ ๊ฒ
ํ ์คํธ ์ฝ๋๋ฅผ ๋จผ์ ์์ฑํ๊ณ ํ ์คํธ๋ฅผ ํต๊ณผ์ํค๊ธฐ ์ํด ๊ฐ๋ฐ์ ์งํ
๋ฏธ๋ฆฌ ์์ ์กฐ๊ฑด์ ์ถฉ์กฑํ์ฌ ๊ฐ๋ฐ์ ํ์ง ์๊ณ ,
ํ ์คํธํ ๋งํผ๋ง ์ฝ๋๋ฅผ ์์ฑ
์ง์์ ์ธ ์ฝ๋ ์ ๋ฆฌ๋ ํฅํ ์ ์ง ๋ณด์ ๋น์ฉ์ ๋ฎ์ถ๋๋ฐ ๋์์ด ๋จ
TDD ํ๋ฆ
์ค๊ณ -> ํ ์คํธ -> ์ฝ๋ฉ -> ๋ฆฌํฉํ ๋ง -> ํ ์คํธ
# Red - Green _Refactor
ํ ์คํธ ์ฝ๋๊ฐ ์คํจ : RED
ํ ์คํธ ์ฝ๋๊ฐ ์ฑ๊ณต: GREEN
๋ฆฌํฉํ ๋ง: REFACTOR
์ฝ๋๋ฅผ ๊ตฌํํด์ ์คํจํ๋ ํ ์คํธ๋ฅผ ํต๊ณผ์ํค๋ ๊ฒ ์๋ฏธ
์๋๋ ๊ฐ๋จํ ๋ง์ ๊ธฐ๋ฅ์ ๊ตฌํํ ํ ์คํธ ์ฝ๋์ด๋ค
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* ๊ธฐ๋ฅ์ ์์ฑํ๋ฉด test package -> main package๋ก ์ด๋
* ์์ฑ๋์ง ์์ ์ฝ๋๊ฐ ๋ฐฐํฌ๋๋ ๊ฒ์ ๋ง๊ธฐ ์ํจ
*/
public class CalculatorTest {
@Test
void plus(){
int result = Calculator.plus(1, 2);
assertEquals(3, result); // ์ค์ ๊ฐ๊ณผ ๋์ผ ํ์ง ๋น๊ต
assertEquals(5, Calculator.plus(4, 1));
}
}
public class Calculator {
public static int plus(int a1, int a2){
return a1+a2;
}
- @Test : ๊ธฐ๋ฅ์ ๊ฒ์ฆํ๋ ํ ์คํธ ๋ฉ์๋๋ก ์ธ์
- assertEquals(): ์ธ์๋ก ๋ฐ์ ๋ ๊ฐ์ด ๋์ผํ์ง ๋น๊ต
ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๊ณ , ํ ์คํธ๊ฐ ๋๋ ํด๋์ค์ ๊ฒฝ์ฐ์๋ test Package ์์ main package๋ก ์ด๋ํ๋ค. ํ ์คํธ ์ค์ธ ์ฝ๋๋ ์์ง ์์ ํ์ง ์์ ์ค์ main package์ ์์ ๊ฒฝ์ฐ ๋ฐฐํฌ๋์ด ์๋น์ค ์ฅ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
๐ TDD ์: ์ํธ ๊ฒ์ฌ๊ธฐ
ํ์ค์ ์ธ ์ํธ ๊ฒ์ฌ๊ธฐ๋ฅผ ๊ตฌํํด๋ณด์.
์ํธ๊ฒ์ฌ๊ธฐ์์๋ ๋ค์๊ณผ ๊ฐ์ด 3๊ฐ์ง์ ๊ท์น์ด ์์ ๊ฒ์ด๋ค.
1. ๊ธธ์ด๊ฐ 8๊ธ์ ์ด์
2. 0๋ถํฐ 9 ์ฌ์ด์ ์ซ์๋ฅผ ํฌํจ
3. ๋๋ฌธ์ ํฌํจ
[๊ฐํจ] ์ธ๊ฐ์ง ๊ท์น์ ๋ชจ๋ ์ถฉ์กฑ [๋ณดํต] 2๊ฐ์ ๊ท์น ์ถฉ์กฑ [์ฝํจ] 1๊ฐ ์ดํ ๊ท์น ์ถฉ์กฑ
1๏ธโฃ ์ฒซ ๋ฒ์งธ ํ ์คํธ: ๋ชจ๋ ๊ท์น์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
TDD๋ฅผ ํ๋ฉด์ ์ค์ํ ๋ถ๋ถ ์ค ํ๋์ด๋ค.
์ฒซ ๋ฒ์ฌ ํ ์คํธ๋ฅผ ์ ์ ํํ์ง ์์ผ๋ฉด ์ดํ ์งํ ๊ณผ์ ์ด ์ํํ๊ฒ ํ๋ฌ๊ฐ์ง ์๋๋ค.
์ฒซ ๋ฒ์งธ์ ๊ฒฝ์ฐ ๊ฐ์ฅ ์ฝ๊ฑฐ๋ ๊ฐ์ฅ ์์ธ์ ์ธ ์ํฉ์ ์ ํํด์ผ ํ๋ค.
์ํธ ๊ฒ์ฌ๊ธฐ์ ๊ฒฝ์ฐ ๋ชจ๋ ๊ท์น์ ์ถฉ์กฑํ๊ฑฐ๋ ๋ชจ๋ ๊ท์น์ ์ถฉ์กฑํ์ง ์๋ ๊ฒ ์ค์์ ์ ํํ๋ฉด ๋๋๋ฐ, ๋ชจ๋ ๊ท์น์ ์ถฉ์กฑํ์ง ์๋ ๊ฒฝ์ฐ๋ ๋ง์ ์์ธ ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ฏ๋ก ๋ชจ๋ ๊ฒ์ฌ ์ฝ๋๋ฅผ ๊ตฌํํด์ผํ๋ค. ๋ฐ๋ผ์ ๋ชจ๋ ๊ท์น์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ๋ฅผ ๊ฐ์ฅ ๋จผ์ ์ดํด๋ณผ ์์ ์ด๋ค.
// ๊ธฐ๋ณธ์ ์ธ ํ
์คํธ ์ฝ๋ ์์ฑ
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class PasswordStrengthMeterTest {
@Test
void meetsAllCriteria_Then_Strong() {
PasswordStrengthMeter meter = new PasswordStrengthMeter();
PasswordStrength result = meter.meter("123ABCDE456");
assertEquals(PasswordStrength.STRONG, result);
}
}
// ํ
์คํธ์ ํ์ํ ์ฝ๋ ์์ฑ ํด๋์ค
public class PasswordStrengthMeter {
public PasswordStrength meter(String s) {
return PasswordStrength.STRONG;
}
}
// enum class
public enum PasswordStrength {
STRONG;
}
2๏ธโฃ ๋ ๋ฒ์งธ ํ ์คํธ: ๊ธธ์ด๋ง 8๊ธ์ ๋ฏธ๋ง์ด๊ณ ๋๋จธ์ง ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
ํจ์ค์๋ ๋ฌธ์์ด์ ๊ธธ์ด๊ฐ 8๊ธ์ ๋ฏธ๋ง์ด๊ณ ๋๋จธ์ง ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ๋ ์ํธ์ ๊ฐ๋๊ฐ ๋ณดํต์ด์ด์ผ ํ๋ค.
public class PasswordStrengthMeter {
public PasswordStrength meter(String s) {
if (s.length() < 8) {
return PasswordStrength.NORMAL;
}
return PasswordStrength.STRONG;
}
}
// ํ
์คํธ ์ฝ๋
@Test
void meetsOtherCriteria_except_for_Length_Then_Normal() {
PasswordStrengthMeter meter = new PasswordStrengthMeter();
PasswordStrength result = meter.meter("ab12!@A");
assertEquals(PasswordStrength.NORMAL, result);
}
// enum class
public enum PasswordStrength {
STRONG, NORMAL;
}
3๏ธโฃ ์ธ ๋ฒ์งธ ํ ์คํธ: ์ซ์๋ฅผ ํฌํจํ์ง ์๊ณ ๋๋จธ์ง ์กฐ๊ฑด์์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
์ซ์๋ฅผ ํฌํจํ์ง ์๋ ๊ฒฝ์ฐ์ด๋ฉฐ, ๋๋จธ์ง ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ์๋ ๋ณดํต ๊ฐ๋์ ์ํธ๋ฅผ ๊ฐ๊ฒ ๋๋ค.
@Test
void meetsOtherCriteria_except_for_Number_Then_Normal() {
PasswordStrengthMeter meter = new PasswordStrengthMeter();
PasswordStrength result = meter.meter("ab!@ABqwer");
assertEquals(PasswordStrength.NORMAL, result);
}
public PasswordStrength meter(String s) {
if (s.length()) {
return PasswordStrength.NORMAL;
}
boolean containsNum - meetsContainingNumberCriteria(s);
if(!containsNum) return PasswordStrength.NORMAL;
return PasswordStrength.STRONG;
}
private boolean meetsContainingNumberCriteria(String s){
for(char ch:s.toCharArray()){
if(ch>'0' && ch<'9'){
return true;
}
}
return false;
}
4๏ธโฃ ์ฝ๋ ๋ฆฌํฉํ ๋ง
ํ ์คํธ ์ฝ๋๋ ์ฝ๋๊ธฐ ๋๋ฌธ์ ์ ์ง๋ณด์์ ๋์์ด๋ค. ํ ์คํธ ๋ฉ์๋์์ ์ค๋ณต์ด ๋ฐ์ํ๋ฉด ์๋ง๊ฒ ์ ๊ฑฐํ๊ฑฐ๋ ์๋ฏธ๊ฐ ์ ๋๋ฌ๋๊ฒ ์ฝ๋๋ฅผ ์์ ํด์ผ ํ๋ค.
ํ์ง๋ง ์ฝ๋๋ฅผ ๋ฌดํฑ๋๊ณ ์์ ํ๋ฉด ์๋๋ค.
์ค๋ณต์ ์ ๊ฑฐํ ํ์๋ ํ ์คํธ ์ฝ๋์ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง์ง ์๊ณ ์์ ์ด ์ฉ์ดํ ๊ฒฝ์ฐ์๋ง ์ค๋ณต์ ์ ๊ฑฐํด์ผ ํ๋ค.
์ค๋ณต์ ์ ๊ฑฐํ ๋ค์ ์คํ๋ ค ํ ์คํธ ์ฝ๋ ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง๋ฉด ์ ๊ฑฐํ๋ ์ค๋ณต์ ๋๋๋ ค์ผ ํ๋ค.
-> ๊ณผ๊ฑฐ, ํญ์ ์ฝ๋๋ ๊ฐ๊ฒฐํ ๊ฒ์ด ์ข๋ค๊ณ ํ์ฌ ์ค๋ณต๋ ๊ฒ์ ๋ชจ๋ extract method๋ก ๋นผ๋์ด์ ์ฌ์ฉํ๋๋ฐ, ์คํ๋ ค ๋ ์ด๋ ์๋ ์๋ค๋ ๊ฒ์ ์๊ฒ ๋์๋ค.
private PasswordStrengthMeter meter = new PasswordStrengthMeter();
private void assertStrength(String password, PasswordStrength expStr){
PasswordStrength result = meter.meter(password);
assertEquals(expStr, result);
}
///
// ๋น ํ
์คํธ ๋ฉ์๋๋ฅผ ์คํํ๋ ๊ฒ ๋ํ ๋๋ฆ๋๋ก ์๋ฏธ๊ฐ ์์
@Test
void name(){
}
@Test // ๋ชจ๋ ๊ท์น์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
void meetsAllCriteria_Then_Strong(){
assertStrength("ab12!@AB", PasswordStrength.STRONG);
assertStrength("abc!Add", PasswordStrength.STRONG);
}
/**
* assertEquals: ๋ ๊ฐ์ด ๊ฐ์์ง ๋น๊ตํ๋ ๋จ์ธ
* ๋จ์ธ: ๊ฐ์ ํน์ ์กฐ๊ฑด์ด ์ถฉ์กฑํ๋์ง ํ์ธํ๊ณ ์ถฉ์กฑํ์ง ์๋ ๊ฒฝ์ฐ์ ์ต์
์
๋ฐ์ -> ํ
์คํธ ์คํจ
*/
@Test // ๊ธธ์ด๋ง 8๊ธ์ ๋ฏธ๋ง์ด๊ณ ๋๋จธ์ง ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
void meetsOtherCriteria_except_for_Length_Then_Normal(){
assertStrength("ab12!@A", PasswordStrength.NORMAL);
}
@Test // ์ซ์๋ฅผ ํฌํจํ์ง ์๊ณ ๋๋จธ์ง ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
void meetOtherCriteria_except_for_number_Then_Normal(){
assertStrength("ab!@ABqwer", PasswordStrength.NORMAL);
}
5๏ธโฃ ๋ค ๋ฒ์งธ ํ ์คํธ: ๊ฐ์ด ์๋ ๊ฒฝ์ฐ
// enum class
public enum PasswordStrength {
STRONG, NORMAL, INVALID;
}
public PasswordStrength meter(String s) {
if(s == null || s.isEmpty()) return PasswordStrength.INVALID;
if (s.length()) {
return PasswordStrength.NORMAL;
}
boolean containsNum - meetsContainingNumberCriteria(s);
if(!containsNum) return PasswordStrength.NORMAL;
return PasswordStrength.STRONG;
}
private boolean meetsContainingNumberCriteria(String s){
for(char ch:s.toCharArray()){
if(ch>'0' && ch<'9'){
return true;
}
}
return false;
}
6๏ธโฃ ๋ค์ฏ ๋ฒ์งธ ํ ์คํธ: ๋๋ฌธ์๋ฅผ ํฌํจํ์ง ์๊ณ ๋๋จธ์ง ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
@Test // ๋๋ฌธ์๋ฅผ ํฌํจํ์ง ์๊ณ ๋๋จธ์ง ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
void meetsOtherCriteria_except_for_Uppercase_Then_Normal(){
assertStrength("ab12!@df", PasswordStrength.NORMAL);
}
public PasswordStrength meter(String s) {
if(s == null || s.isEmpty()) return PasswordStrength.INVALID;
if (s.length()) {
return PasswordStrength.NORMAL;
}
boolean containsNum - meetsContainingNumberCriteria(s);
boolean containsUpp = meetsContainingUppercaseCriteria(s);
if(!containsUpp) return PasswordStrength.NORMAL;
if(!containsNum) return PasswordStrength.NORMAL;
return PasswordStrength.STRONG;
}
private boolean meetsContainingNumberCriteria(String s){
for(char ch:s.toCharArray()){
if(ch>'0' && ch<'9'){
return true;
}
}
return false;
}
private boolean meetsContainingUppercaseCriteria(String s){
for(char ch:s.toCharArray()){
if(Character.isUpperCase(ch)) return true;
}
return false;
}
7๏ธโฃ ์ฌ์ฏ ๋ฒ์งธ ํ ์คํธ: ๊ธธ์ด๊ฐ 8๊ธ์ ์ด์์ธ ์กฐ๊ฑด๋ง ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
// enum class
public enum PasswordStrength {
STRONG, NORMAL, WEAK, INVALID;
}
@Test // ๊ธธ์ด๊ฐ 8๊ธ์ ์ด์์ธ ์กฐ๊ฑด๋ง ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
void meetsOnlyLengthCriteria_Then_Weak(){
assertStrength("abcdefghi", PasswordStrength.WEAK);
}
public PasswordStrength meter(String s) {
if(s == null || s.isEmpty()) return PasswordStrength.INVALID;
boolean lengthEnough = s.length() >=8;
/*if (s.length()) {
return PasswordStrength.NORMAL;
} */
boolean containsNum - meetsContainingNumberCriteria(s);
boolean containsUpp = meetsContainingUppercaseCriteria(s);
// ๋ชจ๋ ์กฐ๊ฑด์ ๋ง์ง ์๋๋ค๋ฉด ์ํธ ๊ฐ๋๊ฐ ๊ฐ์ฅ ๋ฎ๋ค
if(!lengthEnough && !containsUpp && !containsNum) return PasswordStrength.WEAK;
if(!lengthEnough) return PasswordStrength.NORMAL;
if(!containsUpp) return PasswordStrength.NORMAL;
if(!containsNum) return PasswordStrength.NORMAL;
return PasswordStrength.STRONG;
}
private boolean meetsContainingNumberCriteria(String s){
for(char ch:s.toCharArray()){
if(ch>'0' && ch<'9'){
return true;
}
}
return false;
}
private boolean meetsContainingUppercaseCriteria(String s){
for(char ch:s.toCharArray()){
if(Character.isUpperCase(ch)) return true;
}
return false;
}
if ์ ์ ์๋์ ๋๋ ์ด์ ๋
1. ๊ฐ๋ณ ๊ท์น์ ๊ฒ์ฌํ๋ ๋ก์ง
2. ๊ท์น์ ๊ฒ์ฌํ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ์ํธ ๊ฐ๋๋ฅผ ๊ณ์ฐํ๋ ๋ก์ง
์ผ๋ก ๊ตฌ๋ถํ๊ธฐ ์ํจ์ด๋ค.
8๏ธโฃ ์ผ๊ณฑ ๋ฒ์งธ ํ ์คํธ: ์ซ์ ํฌํจ ์กฐ๊ฑด๋ง ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
๋ค๋ฅธ ๋ฌธ์๋ ์์ฑํ์ง ์๊ณ ์ซ์๋ก๋ง ๋์ด ์๋ ๊ฒฝ์ฐ๋ฅผ ์๋ฏธํ๋ค.
// enum class
public enum PasswordStrength {
STRONG, NORMAL, WEAK, INVALID;
}
@Test // ์ซ์ ํฌํจ ์กฐ๊ฑด๋ง ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ , ์ซ์๋ง ์๋ ๊ฒฝ์ฐ
void meetsOnlyNumCriteria_Then_Week(){
assertStrength("12345", PasswordStrength.WEAK);
}
public PasswordStrength meter(String s) {
if(s == null || s.isEmpty()) return PasswordStrength.INVALID;
boolean lengthEnough = s.length() >=8;
/*if (s.length()) {
return PasswordStrength.NORMAL;
} */
boolean containsNum - meetsContainingNumberCriteria(s);
boolean containsUpp = meetsContainingUppercaseCriteria(s);
// ๋ชจ๋ ์กฐ๊ฑด์ ๋ง์ง ์๋๋ค๋ฉด ์ํธ ๊ฐ๋๊ฐ ๊ฐ์ฅ ๋ฎ๋ค
if(!lengthEnough && !containsUpp && !containsNum) return PasswordStrength.WEAK;
if(!lengthEnough && !containsUpp && containsNum) return PasswordStrength.WEAK;
if(!lengthEnough) return PasswordStrength.NORMAL;
if(!containsUpp) return PasswordStrength.NORMAL;
if(!containsNum) return PasswordStrength.NORMAL;
return PasswordStrength.STRONG;
}
private boolean meetsContainingNumberCriteria(String s){
for(char ch:s.toCharArray()){
if(ch>'0' && ch<'9'){
return true;
}
}
return false;
}
private boolean meetsContainingUppercaseCriteria(String s){
for(char ch:s.toCharArray()){
if(Character.isUpperCase(ch)) return true;
}
return false;
}
9๏ธโฃ ์ฌ๋ ๋ฒ์งธ ํ ์คํธ: ๋๋ฌธ์ ํฌํจ ์กฐ๊ฑด๋ง ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
// enum class
public enum PasswordStrength {
STRONG, NORMAL, WEAK, INVALID;
}
@Test // ๋๋ฌธ์ ํฌํจ ์กฐ๊ฑด๋ง ์ถฉ์กฑํ๋ ๊ฒฝ์ฐ
void meetsOnlyUpperCriteria_Then_Week(){
assertStrength("ABZEF", PasswordStrength.WEAK);
}
public PasswordStrength meter(String s) {
if(s == null || s.isEmpty()) return PasswordStrength.INVALID;
boolean lengthEnough = s.length() >=8;
/*if (s.length()) {
return PasswordStrength.NORMAL;
} */
boolean containsNum - meetsContainingNumberCriteria(s);
boolean containsUpp = meetsContainingUppercaseCriteria(s);
// ๋ชจ๋ ์กฐ๊ฑด์ ๋ง์ง ์๋๋ค๋ฉด ์ํธ ๊ฐ๋๊ฐ ๊ฐ์ฅ ๋ฎ๋ค
if(!lengthEnough && !containsUpp && !containsNum) return PasswordStrength.WEAK;
if(!lengthEnough && !containsUpp && containsNum) return PasswordStrength.WEAK;
if(!lengthEnough && containsUpp && !containsNum) return PasswordStrength.WEAK;
if(!lengthEnough) return PasswordStrength.NORMAL;
if(!containsUpp) return PasswordStrength.NORMAL;
if(!containsNum) return PasswordStrength.NORMAL;
return PasswordStrength.STRONG;
}
private boolean meetsContainingNumberCriteria(String s){
for(char ch:s.toCharArray()){
if(ch>'0' && ch<'9'){
return true;
}
}
return false;
}
private boolean meetsContainingUppercaseCriteria(String s){
for(char ch:s.toCharArray()){
if(Character.isUpperCase(ch)) return true;
}
return false;
}
๐ ์ฝ๋ ์ ๋ฆฌ && ์ํ ๋ฒ์งธ ํ ์คํธ: ์๋ฌด ์กฐ๊ฑด๋ ์ถฉ์กฑํ์ง ์๋ ๊ฒฝ์ฐ && ์ฝ๋ ์ ๋ฆฌ: ์ฝ๋ ๊ฐ๋ ์ฑ ๊ฐ์
๋น์ทํ ์ฝ๋๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ ๊ฐ๊ฒฐํ๊ฒ ์ฝ๋๋ฅผ ์ ๋ฆฌํ๋ค.
public class PasswordStrengthMeter {
public PasswordStrength meter(String s){
if(s == null || s.isEmpty()) return PasswordStrength.INVALID;
int metCounts = getMetCriteriaCounts(s); // extract method -> ๊ฐ๋
์ฑ์ ์ํด
// ๊ฐ๋ณ ๊ท์น์ ๊ฒ์ฌํ๋ ๋ก์ง + ๊ท์น์ ๊ฒ์ฌํ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ์ํธ ๊ฐ๋๋ฅผ ๊ณ์ฐํ๋ ๋ก์ง
if(metCounts <= 1) return PasswordStrength.WEAK;
if(metCounts == 2) return PasswordStrength.NORMAL;
return PasswordStrength.STRONG;
}
private int getMetCriteriaCounts(String s) {
int metCounts = 0;
if(s.length() >= 8) metCounts++;
if(meetsContainingNumberCriteria(s)) metCounts++;
if(meetsContainingUppercaseCriteria(s)) metCounts++;
return metCounts;
}
private boolean meetsContainingNumberCriteria(String s) {
for(char ch:s.toCharArray()){
if(ch>='0' && ch<='9'){
return true;
}
}
return false;
}
private boolean meetsContainingUppercaseCriteria(String s){
for(char ch:s.toCharArray()){
if(Character.isUpperCase(ch)){
return true;
}
}
return false;
}
}
1๏ธโฃ1๏ธโฃ ํ ์คํธ์์ ๋ฉ์ธ์ผ๋ก ์ฝ๋ ์ด๋
๋ชจ๋ ๋ค ์์ฑํ ์ฝ๋๋ ํ ์คํธ ํจํค์ง์์ ๋ฉ์ธ ํํค์ง๋ก ์ด๋ํ๋ค.
'Backend Language > TDD' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ฐธ๊ณ ] Mockito ๊ธฐ์ด ์ฌ์ฉ๋ฒ (0) | 2023.02.12 |
---|---|
[TDD Chapter6] ํ ์คํธ ์ฝ๋์ ๊ตฌ์ฑ (0) | 2023.02.04 |
[TDD Chapter5] JUnit 5 ๊ธฐ์ด (1) | 2023.01.27 |
[TDD Chapter4] TDD ๊ธฐ๋ฅ ๋ช ์ธ ์ค๊ณ (0) | 2023.01.21 |
[TDD Chapter3] ํ ์คํธ ์ฝ๋ ์์ฑ ์์ (1) | 2023.01.12 |