KoreaMango ๋‚˜๋ฌด

[iOS] Unit Test - ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์–ด๋–ป๊ฒŒ ํ•˜๋Š”๊ฑด๋ฐ.. (3) ๋ณธ๋ฌธ

iOS/Unit Test

[iOS] Unit Test - ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์–ด๋–ป๊ฒŒ ํ•˜๋Š”๊ฑด๋ฐ.. (3)

KoreaMango 2022. 7. 12. 17:00

๐Ÿ™ˆ์„œ๋ก 

์ด์ œ ์‹ค์ „์œผ๋กœ ๋“ค์–ด๊ฐ€๋ณด์ž. ์˜ˆ์ œ๋กœ Unit Test๋ฅผ ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

@testable

ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์ „์— @testable import [ํƒ€์ผ“ ๋ช…] ๋ผ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ค˜์•ผ ํ•œ๋‹ค.

@testable์€ Unit Test์—์„œ ์‹ค์ œ ์•ฑ ํƒ€๊นƒ์— ์žˆ๋Š” ์ฝ”๋“œ๋“ค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ํ‚ค์›Œ๋“œ์ด๋‹ค.

๋ณดํ†ต ์•ฑ ์ฝ”๋“œ ๋‚ด๋ถ€์—์„œ๋Š” internal ์ˆ˜์ค€์˜ ์ ‘๊ทผ ์ œํ•œ์œผ๋กœ ํƒ€์ž…์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์•ฑ ํƒ€๊นƒ์˜ ํƒ€์ž…๋“ค์— ์™ธ๋ถ€ ํƒ€๊นƒ์—์„œ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•œ๋ฐ, @testable์€ ํ…Œ์ŠคํŠธ ํ•˜๋Š” ๋™์•ˆ์—๋Š” ๋‹ค๋ฅธ ํƒ€๊นƒ์˜ ์ฝ”๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

SUT (System Under Test)

Test ํด๋ž˜์Šค์˜ ์ฒซ ์ค„์— testํ•  ํƒ€์ž…์„ ๋„ฃ์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ ๋‹ค.

setUpWithError๊ฐ€ ๋จผ์ € ํ˜ธ์ถœ๋˜๋‹ˆ๊นŒ ์—ฌ๊ธฐ์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ดˆ๊ธฐํ™” ํ•ด์ค€๋‹ค.

tearDownWithError๊ฐ€ ๋งˆ์ง€๋ง‰์— ํ˜ธ์ถœ๋˜๋ฉฐ ํ”„๋กœํผํ‹ฐ๋ฅผ nil๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค.

๋งˆ์ง€๋ง‰์— nil๋กœ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ์ด ํ”„๋กœํผํ‹ฐ๋Š” ์˜ต์…”๋„๋กœ ๋งŒ๋“ค์–ด์ ธ์•ผ ํ•œ๋‹ค.

setUpWithError์™€ tearDownWithError ๊ฐ€ ๋‚ด๋ถ€์—์„œ super๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๋Š”๋ฐ ํ•ด๋‹น ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค๊ฐ€ XCTestCase๋ฅผ ์ƒ์† ๋ฐ›์•˜๊ณ  ๋ฉ”์„œ๋“œ๋“ค์„ override ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Test ํ•จ์ˆ˜

  1. XCTAssertEqual : ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ๋น„๊ต
  2. XCTAssertGreaterThan : ๋Œ€์†Œ ๋น„๊ต
  3. XCTAssertNil : nil ํŒ๋ณ„
  4. XCTAssertThrowsError : ๋ฌด์—‡์„ throwํ•˜๋Š”์ง€
  5. XCTAssertTure : Bool ๋ฐ˜ํ™˜ ํŒ๋ณ„
  6. ….

Code Coverage

Code Coverage๋Š” ํ…Œ์ŠคํŠธ์˜ ๊ฐ€์น˜๋ฅผ ์ธก์ •ํ•ด์ฃผ๋Š” ํˆด์ด๋‹ค.

์‹ค์ œ ์•ฑ ์ฝ”๋“œ์—์„œ ์–ด๋Š ์ •๋„์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์ง„ํ–‰๋˜์—ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ํˆด์ด๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€…

https://zeddios.tistory.com/1141

ํ…Œ์ŠคํŠธ ๋”๋ธ”

ํ…Œ์ŠคํŠธ ๋”๋ธ”์ด๋ž€ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ ์ด๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฐ์ฒด๋ฅผ ๋งํ•œ๋‹ค. ํ…Œ์ŠคํŠธํ•˜๋Š” ๋™์•ˆ์—๋Š” ํ…Œ์ŠคํŠธ ๋”๋ธ”๊ณผ ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ์ž ๊น ๋ฐ”๊ฟ”์น˜๊ธฐํ•ด์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

1. Dummy (๋ชจ์กฐ์˜, ๊ฐ€์งœ์˜)

Dummy๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ํ…Œ์ŠคํŠธ ๋”๋ธ”์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์–ด ์žˆ์ง€ ์•Š์€, ๋‹จ์ง€ ์ธ์Šคํ„ด์Šคํ™”๋œ ๊ฐ์ฒด๋กœ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— Dummy์˜ ๋ฉ”์„œ๋“œ๋Š” ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

2. Stub (์“ฐ๋‹ค ๋‚จ์€ ๋ฌผ๊ฑด์˜ ํ† ๋ง‰, ๋‚จ์€ ๋ถ€๋ถ„)

Stub์€ Dummy๊ฐ€ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋งŒ๋“ค์–ด ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ๋Œ€์‹ ํ•ด์„œ ๋™์ž‘ํ•ด ์ฃผ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๊ฐ€ ๊ณค๋ž€ํ•œ ๋ถ€๋ถ„์˜ ๊ฐ์ฒด๋ฅผ ๋„๋ ค๋‚ด์–ด ๊ทธ ์—ญํ• ์„ ์ตœ์†Œํ•œ์œผ๋กœ ๋Œ€์‹ ํ•ด ์ค„ ๋งŒํผ๋งŒ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

3. Fake

Fake๋Š” Stub๋ณด๋‹ค ๊ตฌ์ฒด์ ์œผ๋กœ ๋™์ž‘ํ•ด์„œ ์‹ค์ œ ๋กœ์ง์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์‹ค์ œ ์•ฑ์˜ ๋™์ž‘์—์„œ๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์€ ๊ฐ์ฒด๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค. ๋กœ์ง ์ž์ฒด๋Š” ์‹ค์ œ ์•ฑ์˜ ์ฝ”๋“œ์™€ ๋น„์Šทํ•˜์ง€๋งŒ ๊ทธ ๋™์ž‘์„ ๋‹จ์ˆœํ™”ํ•˜์—ฌ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด๋ฅผ Fake ๊ฐ์ฒด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

4. Spy

Spy๋Š” Stub์˜ ์—ญํ• ์„ ๊ฐ€์ง€๋ฉด์„œ ํ˜ธ์ถœ๋œ ๋‚ด์šฉ์— ๋Œ€ํ•œ ๋ฐฉ๋ฒ• ํ˜น์€ ๊ณผ์ • ๋“ฑ ์•ฝ๊ฐ„์˜ ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€, ๋ช‡ ๋ฒˆ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ๋“ฑ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5. Mock

์‹ค์ œ ๊ฐ์ฒด์™€ ๊ฐ€์žฅ ๋น„์Šทํ•˜๊ฒŒ ๊ตฌํ˜„๋œ ์ˆ˜์ค€์˜ ๊ฐ์ฒด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Stub์ด ์ƒํƒœ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ(State Base Test)๋ผ๋ฉด Mock์€ ํ–‰์œ„ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ(Behavior Base Test)๋ผ๊ณ  ์ด์•ผ๊ธฐํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

์ƒํƒœ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ ๊ฐ’๊ณผ ์˜ˆ์ƒ ๊ฐ’์„ ๋น„๊ตํ•˜๋Š” ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ํ…Œ์ŠคํŠธ์ด๋‹ค.

ํ–‰์œ„ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ๋Š” ์˜ˆ์ƒ๋˜๋Š” ํ–‰์œ„๋“ค์— ๋Œ€ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋งŒ๋“ค์–ด ๋†“๊ณ , ์‹œ๋‚˜๋ฆฌ์˜ค๋Œ€๋กœ ๋™์ž‘ํ–ˆ๋Š”์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•œ๋‹ค.

์˜์กด์„ฑ ์ฃผ์ž… (D.I , Dependency Injection)

์˜์กด์„ฑ ์ฃผ์ž…์€ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ์˜์กด์„ฑ์„ ์ œ๊ณตํ•˜๋Š” ๊ธฐ์ˆ ๋กœ ์ค„์—ฌ์„œ D.I(Dependency Injection)์ด๋ผ ํ•œ๋‹ค.

์˜์กด์„ฑ์ด๋ž€?

class Car {
    var wheel: Wheel = Wheel()
}

class Wheel {
    var weight = 10
}

์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ๋‚ด๋ถ€์—์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ์˜์กด์„ฑ(Dependency)์ด๋‹ค.

Car๋ผ๋Š” ํด๋ž˜์Šค๋Š” Wheel์ด๋ผ๋Š” ํด๋ž˜์Šค์— ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ๋ฉ๋‹ˆ๋‹ค.

์˜์กด์„ฑ ์ฃผ์ž…์ด๋ž€?

class Car {
    var wheel: Wheel

    init(wheel: Wheel) {
        self.wheel = wheel
    }
}

class Wheel {
    var weight = 10
}

let myWheel = Wheel()
let myCar = Car(wheel: myWheel)

๋‚ด๋ถ€์—์„œ ์ดˆ๊ธฐํ™”๊ฐ€ ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์™ธ๋ถ€์—์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋‚ด๋ถ€์— ์ฃผ์ž…ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

์œ„ ์ฝ”๋“œ์—์„œ๋Š” myWheel์„ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑํ•˜์—ฌ Car๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ myWheel์„ ์ฃผ์ž… ์‹œ์ผœ์ฃผ๊ณ  ์žˆ๋‹ค.

์˜์กด์„ฑ ์ฃผ์ž…์€ ์™œ ์‚ฌ์šฉํ•˜๋‚˜์š”?

์˜์กด์„ฑ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๊ฐ์ฒด๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

๊ฐ์ฒด ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์œผ๋ฉด ๋ฆฌํŒฉํ† ๋ง์ด ์‰ฝ๊ณ , ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์ด ์‰ฌ์›Œ์ง„๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ํ…Œ์ŠคํŠธ ์ž‘์„ฑํ•˜๊ธฐ

์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋„คํŠธ์›Œํฌ๊ฐ€ ์—†๋Š” ํ™˜๊ฒฝ์—์„œ URL Session์„ ๋™์ž‘์‹œํ‚ฌ ์ˆ˜ ์žˆ์„๊นŒ?

URL Session ํ๋ฆ„

URLSession → datatask → URLSession DataTask → resume → Networking → completion Handler

URLSession์€ URLSessionDataTask๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋„คํŠธ์›Œํ‚น์„ ํ†ตํ•ด ์–ป๊ณ ์ž ํ•˜๋Š” ๊ฐ’์„ ์–ป์–ด์™€์„œcompletionHandler๋ฅผ ์‹คํ–‰ํ•ด ์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ Test Double์„ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์„œ ๋„คํŠธ์›Œํ‚น ์—†์ด completionHandler๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ์„๊นŒ?

ํ•ด๊ฒฐ ๋ฐฉ์•ˆ ์˜ˆ์‹œ

Dummy Data → Stub URLSession → datatask → Stub URLSession DataTask → resume → completion Handler

  • Networking์œผ๋กœ ๋ฐ›์•„์˜ค๋Š” ๋Œ€์‹  ์ง์ ‘ Data๋ฅผ ๋งŒ๋“ค์–ด์„œ CompletionHandler๊นŒ์ง€ ์ „๋‹ฌํ•˜๊ธฐ
  • ๊ธฐ์กด์˜ URLSession๊ณผ URLSessionDataTask ์ž๋ฆฌ์— DummyData๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” Stub ๊ฐ์ฒด ๋งŒ๋“ค์–ด์„œ ๋ฐ”๊ฟ”์น˜๊ธฐ

Dummy์™€ Stub ๋“ฑ์˜ Test Double์„ ํ™œ์šฉํ•˜์—ฌ ๋ฏธ๋ฆฌ request์— ๋Œ€ํ•œ ๋‹ต์„ ์„ค์ •ํ•ด๋‘๊ณ  ์ด๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์‹์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์‹ค์ œ๋กœ ํ…Œ์ŠคํŠธ์—์„œ๋Š” ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ํ•˜์ง€ ์•Š๊ณ  ํ–ˆ๋‹ค๋Š” ๊ฐ€์ • ํ•˜์—  ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋ชจ๋“  ์ƒํ™ฉ์„ ํ†ต์ œํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์–ด๋–ค ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ์ด์–ด๋„ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Stub

์ฆ‰ ,stub์€ ์‹ค์ œ์ฝ”๋“œ๋‚˜ ์•„์ง ์ค€๋น„๋˜์ง€ ๋ชปํ•œ ์ฝ”๋“œ๋ฅผ ๋ฏธ๋ฆฌ ์ •ํ•ด์ง„ ๋‹ต๋ณ€์œผ๋กœ ๊ฐ€์žฅํ•˜๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค.

Stub ํŠน์ง•

  • dummy๊ฐ์ฒด๊ฐ€ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ๋งŒ๋“ค์–ด ๋†“์€ ๊ฐ์ฒด
  • ์‹ค์ œ ์ฝ”๋“œ๋‚˜ ์•„์ง ์ค€๋น„๋˜์ง€ ๋ชปํ•œ ์ฝ”๋“œ์˜ ํ–‰๋™์„ ๊ฐ€์žฅํ•˜๋Š” ํ–‰์œ„
  • ํ˜ธ์ถœ์ž๋ฅผ ์‹ค์ œ ๊ตฌํ˜„๋ฌผ๋กœ ๋ถ€ํ„ฐ ๊ฒฉ๋ฆฌ์‹œํ‚ค๋Š” ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๊ฐ€๋Šฅ
  • ์ธํ„ฐํŽ˜์ด์Šค or ๊ธฐ๋ณธํด๋ž˜์Šค๊ฐ€ ์ตœ์†Œํ•œ์œผ๋กœ ๊ตฌํ˜„๋œ ์ƒํƒœ
  • ํ…Œ์ŠคํŠธ์—์„œ ํ˜ธ์ถœ๋œ ์š”์ฒญ์— ๋Œ€ํ•ด ๋ฏธ๋ฆฌ ์ค€๋น„ํ•ด๋‘” ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Stub์ด ์ฃผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ

  • ๊ตฌํ˜„์ด ๋˜์ง€์•Š์€ ํ•จ์ˆ˜๋‚˜, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ• ๋•Œ
  • ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์„ ์ž„์˜๋กœ ์ƒ์„ฑํ•˜๊ณ  ์‹ถ์„ ๋•Œ
  • ๋ณต์žกํ•œ ๋…ผ๋ฆฌ ํ๋ฆ„์„ ๊ฐ€์ง€๋Š” ๊ฒฝ์šฐ, ํ…Œ์ŠคํŠธ๋ฅผ ๋‹จ์ˆœํ™” ํ•˜๊ณ  ์‹ถ์„ ๋•Œ
  • ์˜์กด์„ฑ์„ ๊ฐ€์ง€๋Š” ์œ ๋‹›์˜ ์‘๋‹ต์„ ๋ชจ์‚ฌํ•˜์—ฌ ๋…๋ฆฝ์ ์ธ ์‹œํ—˜ ์ˆ˜ํ–‰์„ ํ•˜๊ณ ์ž ํ•  ๋•Œ

Test Stub์„ ์‚ฌ์šฉํ•˜์—ฌ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ด์ 

  • ์˜์กดํ•˜๋Š”๊ฒƒ์— ๋Œ€ํ•˜์—ฌ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • interface๋งŒ ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ stub์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด˜์ด˜ํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • stub์œผ๋กœ ๋‹ค์–‘ํ•œ ์‘๋‹ต๊ฒฐ๊ณผ(canned anwser) ์ผ€์ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ™๐Ÿป Ref

https://zeddios.tistory.com/1141

https://yagom.net/courses/unit-test-์ž‘์„ฑํ•˜๊ธฐ/

https://beomseok95.tistory.com/294