🌱TDD: κΈ°λŠ₯ λͺ…세·섀계 & ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ ꡬ성

HyojinΒ·2024λ…„ 8μ›” 25일
0

TDD

λͺ©λ‘ 보기
2/4

CHAPTER 4: κΈ°λŠ₯ λͺ…세·섀계

κΈ°λŠ₯ λͺ…μ„Έ: μž…λ ₯κ³Ό κ²°κ³Ό

μž…λ ₯을 보톡 λ©”μ„œλ“œμ˜ νŒŒλΌλ―Έν„°λ‘œ μ „λ‹¬ν•œλ‹€.

κ²°κ³ΌλŠ” μ—¬λŸ¬ ν˜•μ‹μœΌλ‘œ μ •μ˜ν•  수 μžˆλ‹€. (예) 리턴 κ°’, 읡센μ…₯

κΈ°λŠ₯ μ‹€ν–‰ κ²°κ³Όμ—λŠ” 변경도 ν¬ν•¨ν•œλ‹€. (예) νšŒμ› κ°€μž… κΈ°λŠ₯은 DB에 νšŒμ› 정보λ₯Ό μΆ”κ°€ν•œλ‹€.

섀계 과정을 μ§€μ›ν•˜λŠ” TDD

TDDλŠ” ν…ŒμŠ€νŠΈλ₯Ό λ§Œλ“œλŠ” 것뢀터 μ‹œμž‘ν•œλ‹€.

  • ν…ŒμŠ€νŠΈν•  κΈ°λŠ₯을 μ‹€ν–‰
  • μ‹€ν–‰ κ²°κ³Όλ₯Ό 검증

νƒ€μž…μ˜ 이름을 μ •μ˜ν•˜κ³ , νƒ€μž…μ΄ μ œκ³΅ν•  κΈ°λŠ₯을 κ²°μ •ν•˜λŠ” 것은 기본적인 섀계 ν–‰μœ„μ΄λ‹€.

TDD μžμ²΄λŠ”κ°€ μ„€κ³„λŠ” μ•„λ‹ˆμ§€λ§Œ, TDDλ₯Ό ν•˜λ‹€ 보면 ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” κ³Όμ •μ—μ„œ 일뢀 섀계가 μ§„ν•΄μ•Ÿκ²Œ λœλ‹€.

ν•„μš”ν•œ 만큼 μ„€κ³„ν•˜κΈ°

  • ν•„μš”ν•  κ²ƒμœΌλ‘œ μ˜ˆμΈ‘ν•΄μ„œ 미리 μ½”λ“œλ₯Ό λ§Œλ“€μ§€ μ•ŠλŠ”λ‹€.
    μ‹€μ œ ν…ŒμŠ€νŠΈ 사둀λ₯Ό μΆ”κ°€ν•˜κ³  ν†΅κ³Όμ‹œν‚€λŠ” κ³Όμ •μ—μ„œ ν•„μš”ν•œ 만큼 섀계λ₯Ό λ³€κ²½ν•œλ‹€.
    - 사전 섀계 ν™œλ™μ„ μƒλž΅ν•˜λŠ” 것은 μ•„λ‹ˆλ‹€.
  • TDD둜 κ°œλ°œν•˜λŠ” μ½”λ“œ λΉ„μœ¨μ΄ λ†’μ•„μ§ˆμˆ˜λ‘ μ§€κΈˆ μ‹œμ μ—μ„œ ν•„μš”ν•œ μ„€κ³„λ§Œ μ½”λ“œμ— λ°˜μ˜ν•  κ°€λŠ₯성이 컀진닀. μœ μ—°ν•œ μ„€κ³„λŠ” ν•„μš”ν•œ μ‹œμ μ— μΆ”κ°€ν•œλ‹€.

κΈ°λŠ₯ λͺ…μ„Έ ꡬ체화

ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κΈ° μœ„ν•΄ κ°œλ°œμžλŠ” κΈ°λŠ₯ λͺ…μ„Έλ₯Ό 정리해야 ν•œλ‹€.

μš”κ΅¬μ‚¬ν•­ λͺ…μ„Έμ„œλ‘œλŠ” μƒλž΅λœ λ‚΄μš©μ΄ λ§Žμ€λ° ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ €λ©΄ μž…λ ₯κ³Ό κ²°κ³Όκ°€ λͺ…ν™•ν•΄μ•Ό ν•˜λ―€λ‘œ μ• λ§€ν•œ 점을 λ°œκ²¬ν•˜λ©΄ κΈ°νšμžλ‚˜ 싀무 λ‹΄λ‹Ήμžμ™€ μ–˜κΈ°ν•΄μ„œ 상황에 따라 κΈ°λŠ₯이 μ–΄λ–»κ²Œ λ™μž‘ν•΄μ•Ό ν•˜λŠ”μ§€ ꡬ체적으둜 정리할 수 μžˆλ‹€.

λͺ¨ν˜Έν•œ 상황을 λ§Œλ‚˜λ©΄ 이λ₯Ό ꡬ체적인 예둜 λ°”κΎΈμ–΄ ν…ŒμŠ€νŠΈ μ½”λ“œμ— λ°˜μ˜ν•œλ‹€.

νŠΉμ • μƒν™©μ—μ„œ μ½”λ“œκ°€ μ–΄λ–»κ²Œ λ™μž‘ν•˜λŠ”μ§€ μ΄ν•΄ν•˜κ³  μ‹Άλ‹€λ©΄ ν•΄λ‹Ή 상황을 κ²€μ¦ν•˜λŠ” ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•˜κ³  이해가 ν•„μš”ν•œ μ½”λ“œλ₯Ό μΆ”μ ν•˜λ©΄ λœλ‹€. μ΄λŠ” μœ μ§€λ³΄μˆ˜μ— 큰 도움이 λœλ‹€.

CHAPTER 5: JUnit 5 기초

JUnit 5 λͺ¨λ“ˆ ꡬ성

  • JUnit ν”Œλž«νΌ
  • JUnit μ£Όν”Όν„°
  • JUnit λΉˆν‹°μ§€

@Test μ• λ…Έν…Œμ΄μ…˜κ³Ό ν…ŒμŠ€νŠΈ λ©”μ„œλ“œ

JUnit μ½”λ“œμ˜ κΈ°λ³Έ κ΅¬μ‘°λŠ” @Test μ• λ…Έν…Œμ΄μ…˜μ„ λ©”μ„œλ“œμ— λΆ™μ΄λŠ” 것이닀.

  • @Test μ• λ…Έν…Œμ΄μ…˜μ„ 뢙인 λ©”μ„œλ“œλŠ” private이면 μ•ˆ λœλ‹€.

JUnit Assertions ν΄λž˜μŠ€λŠ” assertEquals() λ©”μ„œλ“œμ™€ 같이 값을 κ²€μ¦ν•˜κΈ° μœ„ν•œ λ‹€μ–‘ν•œ 정적 λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•œλ‹€.

μ£Όμš” 단언 λ©”μ„œλ“œ

  • assertEquals(expected, actual)
  • assertNotEquals(unexpected, actual)
  • assertSame(Object expected, actual) : 두 객체가 λ™μΌν•œ 객체인지 κ²€μ‚¬ν•œλ‹€.
  • assertNotEquals(Object unexpected, actual)
  • assertTrue(boolean condition)
  • assertFalse(boolean condition)
  • assertNull(Object actual)
  • assertNotNull(Object actual)
  • fail() : ν…ŒμŠ€νŠΈ μ‹€νŒ¨ 처리

Assertionsκ°€ μ œκ³΅ν•˜λŠ” μ΅μ…‰μ…˜ λ°œμƒ 유무 검사 λ©”μ„œλ“œ

  • assertThrows(Class<T> expectedType, Executable executable)
  • seertDoesNotThrow( Executable executable)

ν…ŒμŠ€νŠΈ 라이프 사이클

  • @BeforeEach
  • @AfterEach
  • @BeforeAll
  • @AfterAll
public class LifecycleTest {
	public LifecycleTest() {
		System.out.,println("new LifecycleTest");
	}

	@BeforeEach
	void setUp() {
		System.out.,println("setUp");
	}

	@Test
	void a() {
		System.out.,println("A");
	}
	@Test
	void b() {
		System.out.,println("B");
	}
	@BeforeEach
	void tearDown() {
		System.out.,println("tearDown");
	}
}

μ‹€ν–‰ κ²°κ³Ό

new LifecycleTest
setUp
A
tearDown
new LifecycleTest
setUp
B
tearDown
  • @Test λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•  λ•Œλ§ˆλ‹€ 객체λ₯Ό μƒˆλ‘œ μƒμ„±ν•˜λŠ” 점을 μ£Όμ˜ν•˜μž

ν…ŒμŠ€νŠΈ λ©”μ„œλ“œ κ°„ μ‹€ν–‰ μˆœμ„œ 의쑴과 ν•„λ“œ κ³΅μœ ν•˜μ§€ μ•ŠκΈ°

각 ν…ŒμŠ€νŠΈ λ©”μ„œλ“œλŠ” μ„œλ‘œ λ…λ¦½μ μœΌλ‘œ λ™μž‘ν•΄μ•Όν•œλ‹€.

μ„œλ‘œ ν•„λ“œλ₯Ό κ³΅μœ ν•œλ‹€κ±°λ‚˜ μ‹€ν–‰ μˆœμ„œλ₯Ό κ°€μ •ν•˜κ³  ν…ŒμŠ€νŠΈ μž‘μ„±ν•˜μ§€ λ§μ•„μ•Όν•œλ‹€.

JUnit은 ν…ŒμŠ€νŠΈ λ©”μ„œλ“œμ˜ μ‹€ν–‰ μˆœμ„œλ₯Ό μ§€μ •ν•˜λŠ” 방법을 μ œκ³΅ν•˜κ³  μžˆλ‹€, ν•˜μ§€λ§Œ 각 ν…ŒμŠ€νŠΈλŠ” λ…λ¦½μ μœΌλ‘œ λ™μž‘ν•΄μ•Ό ν•œλ‹€. ν…ŒμŠ€νŠΈ λ©”μ„œλ“œ 간에 의쑴이 생기면 μœ μ§€λ³΄μˆ˜λ₯Ό μ–΄λ ΅κ²Œ λ§Œλ“ λ‹€.

μΆ”κ°€ μ• λ…Έν…Œμ΄μ…˜

  • @DisplayName
  • @Disabled

CHAPTER 6: ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ ꡬ성

상황

λ…Έλ ¨ν•œ κ°œλ°œμžλŠ” μ–΄λ–€ 상황이 μ‹€ν–‰ 결과에 영ν–₯을 쀄 수 μžˆλŠ”μ§€ μ°ΎκΈ° μœ„ν•΄ λ…Έλ ₯ν•œλ‹€.

κΈ°λŠ₯μ—μ„œμ˜ 상황

μ£Όμ–΄μ§„ 상황에 따라 κΈ°λŠ₯ μ‹€ν–‰ κ²°κ³ΌλŠ” 달라진닀. μ΄λŠ” ν…ŒμŠ€νŠΈ μ½”λ“œ ꡬ쑰에도 영ν–₯을 μ€€λ‹€.

ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ ꡬ성 μš”μ†Œ: 상황, μ‹€ν–‰, κ²°κ³Ό 확인

given, when, then

μ–΄λ–€ 상황이 μ£Όμ–΄μ§€κ³ , κ·Έ μƒν™©μ—μ„œ κΈ°λŠ₯을 μ‹€ν–‰ν•˜κ³ , μ‹€ν–‰ν•œ κ²°κ³Όλ₯Ό ν™•μΈν•˜λŠ” μ„Έ κ°€μ§€κ°€ ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ κΈ°λ³Έ 골격이닀.

JUnit

JUnitμ—μ„œ 상황을 μ„€μ •ν•˜λŠ” 방법은 ν…ŒμŠ€νŠΈν•  λŒ€μƒμ— 따라 달라진닀.

  • 객체λ₯Ό 생성할 λ•Œ μ •λ‹΅ 숫자λ₯Ό μ§€μ •ν•˜λŠ” 경우
    @Test
    void exactMatch() {
    	// 정닡이 456인 상황
    	BaseballGame game = new BaseballGame("456");
    	// μ‹€ν–‰
    	Score score = game.guess("456)
    	// κ²°κ³Ό 확인
    	assertEquals(3, score.strikes());
    	assertEquals(0, score.balls());
    }
    
    @Test
    void noMatch() {
    	// 정닡이 123인 상황
    	BaseballGame game = new BaseballGame("123");
    	// μ‹€ν–‰
    	Score score = game.guess("456)
    	// κ²°κ³Ό 확인
    	assertEquals(0, score.strikes());
    	assertEquals(0, score.balls());
    }
  • @BeforeEachλ₯Ό μ μš©ν•œ λ©”μ„œλ“œμ—μ„œ 상황을 μ„€μ •ν•  경우
    @BeforeEach
    void givenGame() {
    	BaseballGame game = new BaseballGame("456");
    }
    
    @Test
    void exactMatch() {	// μ‹€ν–‰
    	Score score = game.guess("456)
    	// κ²°κ³Ό 확인
    	assertEquals(3, score.strikes());
    	assertEquals(0, score.balls());
    }
    
    @Test
    void noMatch() {
    	// μ‹€ν–‰
    	Score score = game.guess("456)
    	// κ²°κ³Ό 확인
    	assertEquals(0, score.strikes());
    	assertEquals(0, score.balls());
    }
  • 상황이 μ—†λŠ” 경우
    2μž₯μ—μ„œ μ‚¬μš©ν•œ μ•”ν˜Έ 강도 μΈ‘μ •μ˜ 경우 결과에 영ν–₯을 μ£ΌλŠ” 상황이 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ κΈ°λŠ₯을 μ‹€ν–‰ν•˜κ³  κ²°κ³Όλ₯Ό ν™•μΈν•˜λŠ” μ½”λ“œλ§Œ 포함할 수 μžˆλ‹€.
    @Test
    void meetsAllCriteria_Then_Strong() {	
    	// μ‹€ν–‰
    	PasswordStrengthMeter meter = new PasswordStrengthMeter();
    	PasswordStrength result = meter.meter("ab12!@AB");
    	
    	// κ²°κ³Ό 확인
    	assertEquals(PasswordStrength.STRONG, result);
    }
  • μ‹€ν–‰ κ²°κ³Όλ₯Ό ν™•μΈν•˜λŠ” λ°©λ²•μœΌλ‘œ 리턴 값을 μ‚¬μš©ν•˜λŠ” κ²½μš°λ‚˜ μ΅μ…‰μ…˜μ„ λ°œμƒν•˜λŠ” 방법이 μžˆλ‹€.
    @Test
    void genGame_With_DupBumber_Then_Fail() {	
    	assertThrows(IllegalArgumentException.calss,
    		() -> new BaseballGame("110")
    	);
    }

μ™ΈλΆ€ 상황과 μ™ΈλΆ€ κ²°κ³Ό

상황 섀정은 ν…ŒμŠ€νŠΈ λŒ€μƒλΏλ§Œ μ•„λ‹ˆλΌ μ™ΈλΆ€ μš”μΈλ„ μžˆλ‹€.

File dataFile = new File("file.txt");
long sum = MathUtils.sum(dataFile);

파일이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 상황을 μƒκ°ν•΄λ³΄μž.

  • μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” νŒŒμΌμ„ 경둜둜 μ‚¬μš©ν•  경우
@Test
void noDataFile_Then_Exception() {
	File dataFile = new File("badpath.txt");
	assertThrows(TllegalArgumentException.class,
	() -> MathUtils.sum(dataFile));
}
  • λͺ…μ‹œμ μœΌλ‘œ 파일이 μ—†λŠ” 상황
@Test
void noDataFile_Then_Exception() {
	givenNoFile("badpath.txt");
	File dataFile = new File("badpath.txt");
	assertThrows(TllegalArgumentException.class,
	() -> MathUtils.sum(dataFile));
}

private void givenNoFile(String path) {
	File file = new File(path);
	if (file.exists()) {
		boolean delete = file.delete();
		// ν•΄λ‹Ή κ²½λ‘œμ— 파일이 μ‘΄μž¬ν•˜λŠ”μ§€ κ²€μ‚¬ν•΄μ„œ μ‘΄μž¬ν•  경우 ν•΄λ‹Ή νŒŒμΌμ„ μ‚­μ œν•œλ‹€.
		if (!deleted)
			throw new RuntimeException("faile givenNoFile:" + path);
	}
}
  • 상황에 μ•Œλ§žλŠ” νŒŒμΌμ„ 미리 λ§Œλ“€μ–΄ λ‘”λ‹€.
    λ‹€λ₯Έ κ°œλ°œμžλ„ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•  수 μžˆμ–΄μ•Ό ν•˜λ―€λ‘œ ν…ŒμŠ€νŠΈμ— 맞게 μ€€λΉ„ν•œ νŒŒμΌμ€ 버전 관리 λŒ€μƒμ— μΆ”κ°€ν•œλ‹€.
@Test
void dataFileSumTest() {
 File dataFile = new File("src/test/resources/datafile.txt");
 long sum = MathUtils.sum(dataFile);
 asserEquals(101, sum);
}
  • νŒŒμΌμ„ 미리 λ§Œλ“€μ§€ μ•Šκ³  ν…ŒμŠ€νŠΈ μ½”λ“œμ—μ„œ 상황에 λ§žλŠ” νŒŒμΌμ„ μƒμ„±ν•˜λŠ” 방법
@Test
void dataFileSumTest2() {
	givenDataFile("target/datafile.txt", "1", "2", "3", "4");
 File dataFile = new File("target/datafile.txt");
 long sum = MathUtils.sum(dataFile);
 asserEquals(101, sum);
}

private void givenDataFile(String path, String... lines) {
	try {
		Path dataPath = Paths.get(path);
		if(Files.exists(dataPath)) {
			Files.delete(dataPath);
		}
		Files.write(dataPath, Arrays.asList(lines));
	} catch(IOException e) {
		throw new RuntimeException(e);
	}
}

μ™ΈλΆ€ μƒνƒœκ°€ ν…ŒμŠ€νŠΈ 결과에 영ν–₯을 μ£Όμ§€ μ•Šκ²Œ ν•˜κΈ°

ν…ŒμŠ€νŠΈ μ½”λ“œλŠ” ν•œ 번만 μ‹€ν–‰ν•˜κ³  λλ‚˜μ§€ μ•ŠλŠ”λ‹€.

κ°„ν—μ μœΌλ‘œ μ‹€νŒ¨ν•˜κ±°λ‚˜ μ„±κ³΅ν•˜λ©΄ ν…ŒμŠ€νŠΈ 신뒰도가 λ–¨μ–΄μ§„λ‹€.

  • 예): DB 데이터 μƒνƒœμ— 따라 ν…ŒμŠ€νŠΈκ°€ μ„±κ³΅ν•˜κΈ°λ„ ν•˜κ³  μ‹€νŒ¨ν•˜λŠ” 경우

해결방법은 ν…ŒμŠ€νŠΈ μ‹€ν–‰ 전에 μ™ΈλΆ€λ₯Ό μ›ν•˜λŠ” μƒνƒœλ‘œ λ§Œλ“€κ±°λ‚˜ ν…ŒμŠ€νŠΈ μ‹€ν–‰ 후에 μ™ΈλΆ€ μƒνƒœλ₯Ό μ›λž˜λŒ€λ‘œ 되돌렀 놓아야 ν•œλ‹€.

μ™ΈλΆ€ μƒνƒœμ™€ ν…ŒμŠ€νŠΈ 어렀움

상황과 결과에 영ν–₯을 μ£ΌλŠ” μ™ΈλΆ€ μš”μΈμ€ 파일, DBMS, μ™ΈλΆ€ μ„œλ²„ REST API λ“± λ‹€μ–‘ν•˜λ‹€.

μ™ΈλΆ€ 상황은 ν…ŒμŠ€νŠΈ μ½”λ“œμ—μ„œ λ§ˆμŒλŒ€λ‘œ μ œμ–΄ν•  수 μ—†λŠ” κ²½μš°λ„ μžˆλ‹€.

ν…ŒμŠ€νŠΈ λŒ€μƒμ˜ 상황과 결과에 μ™ΈλΆ€ μš”μΈμ΄ κ΄€μ—¬ν•  경우 λŒ€μ—­μ„ μ‚¬μš©ν•˜λ©΄ ν…ŒμŠ€νŠΈ μž‘μ„±μ΄ μ‰¬μ›Œμ§„λ‹€.

λŒ€μ—­μ€ ν…ŒμŠ€νŠΈ λŒ€μƒμ΄ μ˜μ‘΄ν•˜λŠ” λŒ€μƒμ˜ μ‹€μ œ κ΅¬ν˜„μ„ λŒ€μ‹ ν•˜λŠ” κ΅¬ν˜„μΈλ° 이 λŒ€μ—­μ„ ν†΅ν•΄μ„œ μ™ΈλΆ€ μƒν™©μ΄λ‚˜ κ²°κ³Όλ₯Ό λŒ€μ²΄ν•  수 μžˆλ‹€.

λŠλ‚€ 점

  1. κΈ°λŠ₯ λͺ…세와 μ„€κ³„μ˜ μ€‘μš”μ„±: ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•˜κΈ° 전에 κΈ°λŠ₯ λͺ…μ„Έλ₯Ό λͺ…ν™•νžˆ ν•˜κ³ , 섀계λ₯Ό μ΅œμ†Œν•œμœΌλ‘œ μœ μ§€ν•˜λ©° ν•„μš”ν•œ μ‹œμ μ—λ§Œ 섀계λ₯Ό λ°œμ „μ‹œν‚€λŠ” 접근이 ν•„μš”ν•©λ‹ˆλ‹€. μ΄λŠ” μœ μ—°ν•˜κ³  ν™•μž₯ κ°€λŠ₯ν•œ μ½”λ“œλ₯Ό μž‘μ„±μ΄ κ°€λŠ₯ν•˜κ³  μœ μ§€λ³΄μˆ˜μ— μ’‹μŠ΅λ‹ˆλ‹€.
  2. TDD와 μ„€κ³„μ˜ 관계: TDDλŠ” 섀계λ₯Ό μ§μ ‘μ μœΌλ‘œ μˆ˜ν–‰ν•˜λŠ” 것은 μ•„λ‹ˆμ§€λ§Œ, ν…ŒμŠ€νŠΈ μž‘μ„± κ³Όμ •μ—μ„œ μžμ—°μŠ€λŸ½κ²Œ 섀계가 μ΄λ£¨μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.
  3. ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ ꡬ쑰: ν…ŒμŠ€νŠΈ μ½”λ“œλŠ” μ£Όμ–΄μ§„ 상황(given), κ·Έ μƒν™©μ—μ„œμ˜ μ‹€ν–‰(when), 그리고 κ·Έ κ²°κ³Όλ₯Ό ν™•μΈν•˜λŠ”(then) μ„Έ κ°€μ§€λ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€. 이 κ΅¬μ‘°λŠ” ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ 가독성을 높이고, 논리적인 흐름을 λͺ…ν™•νžˆ ν•˜λŠ” 데 μœ μš©ν•©λ‹ˆλ‹€.
  4. μ™ΈλΆ€ μš”μΈμ˜ 관리: ν…ŒμŠ€νŠΈ 결과에 영ν–₯을 쀄 수 μžˆλŠ” μ™ΈλΆ€ μš”μΈ(예: 파일, λ°μ΄ν„°λ² μ΄μŠ€, μ™ΈλΆ€ API)듀을 κ΄€λ¦¬ν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€. 해결방법은 ν…ŒμŠ€νŠΈ μ‹€ν–‰ 전에 μ™ΈλΆ€λ₯Ό μ›ν•˜λŠ” μƒνƒœλ‘œ λ§Œλ“€κ±°λ‚˜ ν…ŒμŠ€νŠΈ μ‹€ν–‰ 후에 μ™ΈλΆ€ μƒνƒœλ₯Ό μ›λž˜λŒ€λ‘œ 되돌렀 놓아야 ν•©λ‹ˆλ‹€.
  5. λŒ€μ—­μ˜ μ‚¬μš©: μ™ΈλΆ€ μ˜μ‘΄μ„±μ„ ν…ŒμŠ€νŠΈμ—μ„œ μ œμ–΄ν•˜κΈ° μ–΄λ €μšΈ λ•Œ, λŒ€μ—­(Stub, Mock λ“±)을 μ‚¬μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈλ₯Ό λ‹¨μˆœν™”ν•˜κ³ , 신뒰성을 높일 수 μžˆμŠ΅λ‹ˆλ‹€.
profile
μ–΄μ œμ˜ λ‚˜λ³΄λ‹€ μ„±μž₯ν•œ μ‚¬λžŒμ΄ 될 수 μžˆλ„λ‘ λ…Έλ ₯ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

0개의 λŒ“κΈ€