Post

FEํ…Œ์ŠคํŠธ(2) - vitest

๐Ÿ“Œ์‹œ์ž‘ํ•˜๋ฉฐ

์ด์ „ ํฌ์ŠคํŒ…์—์„œ ํ…Œ์ŠคํŠธ์— ์•ž์„œ ํ…Œ์ŠคํŠธ์˜ ๋ฐฐ๊ฒฝ๊ณผ ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ดํŽด๋ดค๋‹ค๋ฉด, ์ด๋ฒˆ์—๋Š” ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ api๋ฅผ ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

โœ…it

it ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ํŠน์ • ๋™์ž‘์ด๋‚˜ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ๊ธฐ๋Œ€๋ฅผ ์ •์˜ํ•˜๊ณ , ์ด๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์•ˆ์— ์ž‘์„ฑํ•˜๊ฒŒ ๋œ๋‹ค. it ํ•จ์ˆ˜ ์•ˆ์— ์ž‘์„ฑ๋˜๋Š” ์„ค๋ช…์€ ํ…Œ์ŠคํŠธ ๋ชฉ์ , ๊ธฐ๋Œ€ ๊ฒฐ๊ณผ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋„๋ก ํ•œ๋‹ค.

๋˜ํ•œ, it ํ•จ์ˆ˜๋Š” test ํ•จ์ˆ˜์˜ alias(๋Œ€์ฒด ์ด๋ฆ„)์œผ๋กœ, ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ, ๋‚˜๋Š” it์œผ๋กœ ์ž‘์„ฑํ•˜๋Š”๊ฑธ ์„ ํ˜ธํ•œ๋‹ค.

1
2
3
4
5
6
import { it, expect } from "vitest"

it("2์™€ 3์„ ๋”ํ•˜๋ฉด 5๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค.", () => {
  const result = 2 + 3
  expect(result).toBe(5)
})

โœ…desribe

describe๋Š” it์ด๋‚˜ test๋กœ ์ž‘์„ฑ๋œ ์—ฌ๋Ÿฌ ๊ฐœ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๊ทธ๋ฃนํ™”ํ•ด ์ปดํฌ๋„ŒํŠธ ์•ˆ์˜ ์—ฌ๋Ÿฌ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ€๋…์„ฑ ์žˆ๊ฒŒ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
import { describe, it, expect } from "vitest"

describe("๊ณ„์‚ฐ ๊ธฐ๋Šฅ", () => {
  it("2์™€ 3์„ ๋”ํ•˜๋ฉด 5๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค.", () => {
    const result = 2 + 3
    expect(result).toBe(5)
  })

  it("5์—์„œ 2๋ฅผ ๋นผ๋ฉด 3์ด ๋˜์–ด์•ผ ํ•œ๋‹ค.", () => {
    const result = 5 - 2
    expect(result).toBe(3)
  })
})

โœ…expect

๊ฒฐ๊ณผ๋ฅผ ์ตœ์ข…์ ์œผ๋กœ ๊ฒ€์ฆํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค. expect๋Š” ๋‹จ์–ธ๋ฌธ์œผ๋กœ์จ, ํŠน์ • ์กฐ๊ฑด์ด๋‚˜ ์ƒํƒœ๊ฐ€ ์ฐธ์ธ์ง€ ํ™•์ธํ•œ๋‹ค. ์œ„์—์„œ ์‚ดํŽด๋ณธ ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด expect๋ฅผ ์œ„์— ํ•ด๋‹น ๊ธฐ๋Šฅ์˜ ๊ฐ’์ด 5์ผ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ๋‹จ์–ธํ•˜๊ณ  ์ด๋ฅผ ๊ธฐ์ค€์„ ๋‘๊ณ  ์ฐธ๊ณผ ๊ฑฐ์ง“์„ ํŒ๋ณ„ํ•˜๊ฒŒ ๋œ๋‹ค.

1
2
3
4
5
6
import { it, expect } from "vitest"

it("2์™€ 3์„ ๋”ํ•˜๋ฉด 5๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค.", () => {
  const result = 2 + 3
  expect(result).toBe(5)
})

โžก๏ธmatcher

expect๋ฅผ ์ด์šฉํ•  ๋•Œ matcher๋ฅผ ์ด์šฉํ•ด ์–ด๋–ค ๊ฐ’์„ ๊ธฐ๋Œ€ํ•˜๋Š”์ง€ ์ •ํ™•ํžˆ ์ž‘์„ฑํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์œ„์—์„œ ๋ณธ ์˜ˆ์‹œ๋ฅผ ๋‹ค์‹œ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด๋ฉด,

1
expect(result).toBe(5)

์ด๋ ‡๊ฒŒ expect ๋’ค์— toBe๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด์žˆ๋Š”๋ฐ ์ด ๋œป์€ โ€˜5โ€™๊ฐ€ ๋ ๊ฒƒ์ด๋‹ค. ๋ผ๋Š” ์˜๋ฏธ๋กœ ๊ธฐ๋Œ€ํ•œ๋‹ค โ€˜๋ฌด์—‡์ด ๋ ์ง€โ€™ ์— โ€˜๋ฌด์—‡์ด ๋ ์ง€โ€™์˜ ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

matcher์—๋Š” ๋‹ค์–‘ํ•œ ๊ฒƒ๋“ค์ด ์žˆ๋Š”๋ฐ, ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿ’ŸtoBe / toEqual / toStrictEqual

  • toBe ๋Š” ๊ฐ’์ด ์—„๊ฒฉํ•˜๊ฒŒ ๋™์ผ(===)ํ•œ์ง€ ํ™•์ธํ•œ๋‹ค.
  • toEqual ์€ ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด ๊ฐ’์„ ๋น„๊ตํ•œ๋‹ค.
  • toStrictEqual ์€ undefined ์†์„ฑ๊นŒ์ง€ ํฌํ•จํ•ด ๋” ์—„๊ฒฉํžˆ ํ™•์ธํ•œ๋‹ค.
1
2
expect(2 + 2).toBe(4)
expect({ a: 1 }).toEqual({ a: 1 })

๐Ÿ’ŸtoBeTruthy / toBeFalsy

  • toBeTruthy ๋Š” ๊ฐ’์ด truthyํ•œ์ง€ (์ฆ‰, true๋กœ ํ‰๊ฐ€๋˜๋Š”์ง€) ํ™•์ธํ•œ๋‹ค.
  • toBeFalsy ๋Š” ๊ฐ’์ด falsy(์ฆ‰, false๋กœ ํ‰๊ฐ€๋˜๋Š”์ง€) ํ™•์ธํ•œ๋‹ค.
1
2
expect(true).toBeTruthy()
expect(0).toBeFalsy()

๐Ÿ’ŸtoBeNull / toBeUndefined / toBeDefined

  • toBeNull ์€ ๊ฐ’์ด null์ธ์ง€ ํ™•์ธํ•œ๋‹ค.
  • toBeUndefined undefined์ธ์ง€ ํ™•์ธํ•œ๋‹ค.
  • toBeDefined ๋Š” ๊ฐ’์ด ์ •์˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
1
2
expect(null).toBeNull()
expect(undefined).toBeUndefined()

๐Ÿ’ŸtoBeGreaterThan / toBeLessThan / toBeGreaterThanOrEqual / toBeLessThanOrEqual

  • toBeGreaterThan ์€ ๊ฐ’์ด ๋‹ค๋ฅธ ๊ฐ’๋ณด๋‹ค ํฐ์ง€ ํ™•์ธํ•œ๋‹ค.
  • toBeLessThan ์€ ๊ฐ’์ด ๋‹ค๋ฅธ ๊ฐ’๋ณด๋‹ค ์ž‘์€์ง€ ํ™•์ธํ•œ๋‹ค.
  • toBeGreaterThanOrEqaul ์€ ๊ฐ’์ด ๋‹ค๋ฅธ ๊ฐ’๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€์ง€ ํ™•์ธํ•œ๋‹ค.
  • toBeLessThanOrEqaul ์€ ๊ฐ’์ด ๋‹ค๋ฅธ ๊ฐ’๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€์ง€ ํ™•์ธํ•œ๋‹ค.
1
2
expect(10).toBeGreaterThan(5)
expect(5).toBeLessThanOrEqual(5)

๐Ÿ’Ÿ toContain / toContainEqual

  • toContain์€ ๋ฐฐ์—ด์ด๋‚˜ ๋ฌธ์ž์—ด์— ํŠน์ • ๊ฐ’์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  • toContainEqual์€ ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์— ํŠน์ • ๊ฐ’์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
1
2
expect([1, 2, 3]).toContain(2)
expect([{ a: 1 }, { b: 2 }]).toContainEqual({ b: 2 })

๐Ÿ’ŸtoHaveLength / toHaveProperty

  • toHaveLength๋Š” ๋ฐฐ์—ด, ๋ฌธ์ž์—ด ๋“ฑ์˜ ๊ธธ์ด๊ฐ€ ํŠน์ • ๊ฐ’๊ณผ ๋™์ผํ•œ์ง€ ํ™•์ธํ•œ๋‹ค.
  • toHaveProperty๋Š” ๊ฐ์ฒด๊ฐ€ ํŠน์ • ์†์„ฑ์„ ๊ฐ–๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
1
2
expect([1, 2, 3]).toHaveLength(3)
expect({ a: 1, b: 2 }).toHaveProperty("b")

๐Ÿ’Ÿ toThrowError / toThrowErrorMatchingSnapshot

  • toThrowError๋Š” ํ•จ์ˆ˜๊ฐ€ ํŠน์ • ์—๋Ÿฌ๋ฅผ ๋˜์ง€๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  • toThrowErrorMatchingSnapshot์€ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ์Šค๋ƒ…์ƒท ๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

์Šค๋ƒ…์ƒท: ํŠน์ • ์‹œ์  ๋ฐ์ดํ„ฐ๋‚˜ ์‹œ์Šคํ…œ ์ƒํƒœ๋ฅผ ์ €์žฅํ•ด ๋†“๋Š” ๊ฒƒ

1
2
3
expect(() => {
  throw new Error("error message")
}).toThrowError("error message")

๐Ÿ’Ÿ toHaveBeenCalled / toHaveBeenCalledTimes / toHaveBeenCalledWith

  • toHaveBeenCalled๋Š” ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  • toHaveBeenCalledTimes๋Š” ํ˜ธ์ถœ ํšŸ์ˆ˜๋ฅผ ํ™•์ธํ•œ๋‹ค.
  • toHaveBeenCalledWith๋Š” ํ˜ธ์ถœ๋œ ์ธ์ž(ํ•จ์ˆ˜๋‚˜ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋–„ ์ „๋‹ฌ๋œ ๊ฐ’)๋ฅผ ํ™•์ธํ•œ๋‹ค.
1
2
3
4
5
const mockFn = vi.fn()
mockFn("์ธ์ž")

expect(mockFn).toHaveBeenCalled()
expect(mockFn).toHaveBeenCalledWith("์ธ์ž")

๐Ÿ’Ÿresolves / rejects

  • resolves๋Š” ํ”„๋กœ๋ฏธ์Šค๊ฐ€ resolves(ํ•ด๊ฒฐ) ๋˜์—ˆ์„ ๋•Œ์˜ ๊ฐ’์„ ํ…Œ์ŠคํŠธํ•œ๋‹ค.
  • rejects๋Š” ํ”„๋กœ๋ฏธ์Šค๊ฐ€ rejects(๊ฑฐ๋ถ€) ๋˜์—ˆ์„ ๋•Œ์˜ ๊ฐ’์„ ํ…Œ์ŠคํŠธํ•œ๋‹ค.
1
2
await expect(Promise.resolve("success")).resolves.toBe("success")
await expect(Promise.reject("error")).rejects.toBe("error")

๐Ÿ’Ÿexpect.any / expect.anything

  • expect.any(Class)๋Š” ๊ฐ’์ด ํŠน์ • ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ธ์ง€ ํ™•์ธํ•œ๋‹ค.
  • expect.anything()์€ null๊ณผ undefined๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๊ฐ’์— ๋Œ€ํ•ด ์„ฑ๊ณตํ•œ๋‹ค.
1
2
expect(123).toEqual(expect.any(Number))
expect("์•„๋ฌด๊ฑฐ๋‚˜ ์ „๋ถ€ ์„ฑ๊ณต!").toEqual(expect.anything())

โœ…vi

vi๋Š” ๋ชจ๋“ˆ์„ ๋ชจํ‚น(mocking) ํ•˜๊ฑฐ๋‚˜, ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

  • ๋ชจํ‚น(mocking): ํŠน์ • ๊ธฐ๋Šฅ์ด๋‚˜ ๊ฐ์ฒด์˜ ๋™์ž‘์„ ํ‰๋‚ด๋‚ด๊ฑฐ๋‚˜ ๋Œ€์ฒดํ•œ๋‹ค.

๋ง์ด ์ข€ ์ดํ•ด๊ฐ€ ์–ด๋ ค์šด๋ฐ, A ๋กœ์ง์ด ๋ฌด์–ธ๊ฐ€(B)๋ฅผ ์˜์กดํ•ด์„œ ๊ตฌํ˜„๋œ๋‹ค๊ณ  ๊ฐ€์ €ํ•ด๋ณด์ž. ์ด๋•Œ A ๋กœ์ง ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด์„œ๋Š” B๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ, B๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ๋ณต์žกํ•  ๋•Œ๋Š” ๋ชจํ‚น์„ ํ†ตํ•ด B๋ฅผ ๋Œ€์ฒดํ•˜์—ฌ A ๋กœ์ง์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

โžก๏ธ ๋ชจํ‚น

๋ชจํ‚น์€ vi.fn()์„ ์‚ฌ์šฉํ•ด ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„ํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํŠน์ • ๋กœ์ง์„ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์ƒ์˜ ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

1
vi.fn()

โžก๏ธ ์ŠคํŒŒ์ด

vi.spyOn()์„ ์‚ฌ์šฉํ•ด ํŠน์ • ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ์‹œํ•ด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€, ์–ด๋–ค ์ธ์ž๋กœ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

1
const spy = vi.spyOn(๊ฐ์ฒด, "๊ฐ์ฒด ์•ˆ์˜ ๋ฉ”์†Œ๋“œ ์ด๋ฆ„")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { describe, it, expect } from "vitest"

const calculator = {
  add: (a: number, b: number) => a + b,
}

describe("๊ณ„์‚ฐ ๊ธฐ๋Šฅ", () => {
  it("2์™€ 3์„ ๋”ํ•˜๋ฉด 5๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค.", () => {
    // ์ŠคํŒŒ์ด ์ƒ์„ฑ
    const spy = vi.spyOn(calculator, "add") //calculator ๊ฐ์ฒด์™€ ๊ฐ์ฒด์•ˆ์˜ ๋ฉ”์†Œ๋“œ

    // ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
    const result = calculator.add(2, 3) //์œ„์—์„œ ์ •์˜ํ•œ add ๋ฉ”์†Œ๋“œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ด

    // ๊ฒฐ๊ณผ ํ™•์ธ
    expect(result).toBe(5) // ๊ฒฐ๊ณผ๊ฐ€ 5์ธ์ง€ ํ™•์ธ

    // ์ŠคํŒŒ์ด๋ฅผ ์‚ฌ์šฉํ•ด ํ˜ธ์ถœ ์—ฌ๋ถ€ ๋ฐ ์ธ์ž ํ™•์ธ
    expect(spy).toHaveBeenCalled() // add ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ
    expect(spy.mock.calls[0]).toEqual([2, 3]) // ์ฒซ ๋ฒˆ์งธ ํ˜ธ์ถœ์˜ ์ธ์ž๊ฐ€ [2, 3]์ธ์ง€ ํ™•์ธ
  })
})

โžก๏ธ ํƒ€์ด๋จธ ๋ชจํ‚น

setTimeout์ด๋‚˜ setInterval์„ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ…Œ์ŠคํŠธํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์ ์ • ์‹œ๊ฐ„์ด ์ง€๋‚œ ํ›„์˜ ๋ฐ˜์‘์„ ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ…Œ์ŠคํŠธ๋•Œ๋งˆ๋‹ค ๊ทธ ์‹œ๊ฐ„์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค๋ฉด ๋ฌด์ฒ™ ๋ฒˆ๊ฑฐ๋กœ์šธ ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ, ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ์—๋Š” vi.useFakeTimers()๋ฅผ ์‚ฌ์šฉํ•ด ํƒ€์ด๋จธ๋ฅผ ๋ชจํ‚นํ•˜์—ฌ setTimeout, setInterval ๋“ฑ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด, 5์ดˆ ํ›„์— ์‹คํ–‰ ๋˜์–ด์•ผ ํ•˜๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ์กด์žฌํ•œ๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ, ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด 5์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋งŒ, ๊ฐ€์งœ ํƒ€์ด๋จธ๋ฅผ ์‹คํ–‰ํ•œ ๊ฒฝ์šฐ ๋‹ค๋ฅธ ๋กœ์ง์—๋„ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, vi.useRealTimers() ๋ฅผ ์ด์šฉํ•ด ์›๋ž˜ ํƒ€์ด๋จธ๋กœ ๋ณต๊ตฌํ•ด์•ผํ•จ์— ์œ ์˜ํ•œ๋‹ค.

1
vi.useFakeTimers()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { vi, expect, it } from "vitest"

function runAfterDelay(callback: () => void, delay: number) {
  setTimeout(callback, delay)
}

it("ํƒ€์ด๋จธ๊ฐ€ 5์ดˆ ํ›„์— ๋™์ž‘ํ•ด์•ผ ํ•จ", () => {
  // ํƒ€์ด๋จธ๋ฅผ ๋ชจํ‚น
  vi.useFakeTimers()

  // ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ŠคํŒŒ์ด๋กœ ์„ค์ •
  const callback = vi.fn()

  // ํ•จ์ˆ˜ ํ˜ธ์ถœ
  runAfterDelay(callback, 5000)

  // ์•„์ง ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋˜์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธ
  expect(callback).not.toHaveBeenCalled()

  // 5์ดˆ๋กœ ํƒ€์ด๋จธ ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰
  vi.advanceTimersByTime(5000)

  // ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋˜์—ˆ๋Š”์ง€ ํ™•์ธ
  expect(callback).toHaveBeenCalled()

  // ํƒ€์ด๋จธ ๋ณต๊ตฌ (์›๋ž˜์˜ ํƒ€์ด๋จธ๋กœ ๋Œ์•„๊ฐ€๊ธฐ)
  vi.useRealTimers()
})

โœ…beforeEach & beforeAll

before~์ด๋ž€ ์ด๋ฆ„์—์„œ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋“ฏ์ด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋งˆ๋‹ค ๋ฐ˜๋ณต์ ์ธ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ, before~๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•œ ๋ฒˆ์— ๊น”๋”ํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

  • beforeEach: ๊ฐ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „์— ํŠน์ • ์ž‘์—… ์ˆ˜ํ–‰
  • beforeAll: ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์‹คํ–‰ ์ „ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ํŠน์ • ์ž‘์—… ์ˆ˜ํ–‰ (์ดˆ๊ธฐํ™” ์ž‘์—… ๋“ฑ)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { describe, beforeEach, beforeAll, it, expect } from "vitest"

let counter = 0

describe("beforeEach vs beforeAll ์ฐจ์ด์ ", () => {
  // ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰
  beforeAll(() => {
    counter = 10 // ๋ชจ๋“  ํ…Œ์ŠคํŠธ์— ์ ์šฉํ•  ์ดˆ๊ธฐ ์„ค์ • (์ตœ์ดˆ 1ํšŒ ์‹คํ–‰)
  })

  // ๊ฐ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „์— ์‹คํ–‰
  beforeEach(() => {
    counter += 1 // ํ…Œ์ŠคํŠธ๋งˆ๋‹ค ๊ฐœ๋ณ„์ ์œผ๋กœ ์‹คํ–‰ํ•  ์ž‘์—… (๊ฐ ํ…Œ์ŠคํŠธ ๋งˆ๋‹ค 1ํšŒ ์‹คํ–‰)
  })

  it("์ฒซ ๋ฒˆ์งธ ํ…Œ์ŠคํŠธ", () => {
    expect(counter).toBe(11) // beforeAll์˜ 10๊ณผ beforeEach +1 ์— ์˜ํ•ด 11
  })

  it("๋‘ ๋ฒˆ์งธ ํ…Œ์ŠคํŠธ", () => {
    expect(counter).toBe(12) // ์ฒซ ๋ฒˆ์งธ ํ…Œ์ŠคํŠธ ํ›„ beforeEach๋งŒ ์žฌ์‹คํ–‰๋˜์–ด +1 ์ฆ‰ 12
  })
})

โœ…afterEach & afterAll

beforeEach์™€ beforeAll๊ณผ ๋ฐ˜๋Œ€๋กœ, ํ…Œ์ŠคํŠธ ํ›„์— ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  • afterEach: ๊ฐ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ํ›„์— ํŠน์ • ์ž‘์—… ์ˆ˜ํ–‰
  • afterAll: ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์‹คํ–‰ ํ›„ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ํŠน์ • ์ž‘์—… ์ˆ˜ํ–‰
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { describe, afterEach, afterAll, it, expect } from "vitest"

let counter = 0

describe("afterEach์™€ afterAll ์ฐจ์ด์ ", () => {
  // ๊ฐ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ํ›„์— ์‹คํ–‰
  afterEach(() => {
    counter -= 1 // ๊ฐ ํ…Œ์ŠคํŠธ๊ฐ€ ๋๋‚œ ํ›„ -1
  })

  // ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ๋๋‚œ ํ›„์— ์‹คํ–‰
  afterAll(() => {
    counter -= 2
  })

  it("์ฒซ ๋ฒˆ์งธ ํ…Œ์ŠคํŠธ", () => {
    counter += 1 // ์ดˆ๊ธฐ๊ฐ’ 0 ์— + 1 = 1
    expect(counter).toBe(1) // 1์ด ๋˜์–ด์•ผ ํ•จ
  })

  //์ดํ›„ afterEach๊ฐ€ ์‹คํ–‰ ๋˜์–ด 1 - 1 = 0

  it("๋‘ ๋ฒˆ์งธ ํ…Œ์ŠคํŠธ", () => {
    counter += 1 // 0์— + 1 = 1
    expect(counter).toBe(1) // 1์ด ๋˜์–ด์•ผ ํ•จ
  })

  //๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์ข…๋ฃŒ ๋˜์–ด afterAll ์‹คํ–‰ 1 - 2 = -1
  //์ด ์‹œ์ ์—์„œ counter๋Š” -1
})

๐Ÿ—‚๏ธ์ฐธ๊ณ  ์‚ฌ์ดํŠธ

This post is licensed under CC BY 4.0 by the author.