> [!date] published: 2025-06-07 ## Mock 함수 정리 ### `jest.clearAllMocks()` [jest.clearAllMocks() · Jest](https://jestjs.io/docs/jest-object#jestclearallmocks) > mock 함수의 호출 기록을 삭제 모든 mock들의 아래 프로퍼티들을 초기화한다. - `mock.calls` : 호출 횟수와 호출할 때 사용한 인수 - `mock.instances` : 인스턴스 기록 - `mock.contexts` : this context - `mock.results` : 반환 결과 기록 모든 Mock 함수들에서 `.mockClear()`를 호출한 것과 동일하다. 유지되는 내용... - `mockReturnValue` - `mockImplementation` ```ts describe("clearAllMocks", () => { const mockFn = jest.fn().mockReturnValue("mocked value"); beforeEach(() => { jest.clearAllMocks(); // 호출 기록만 초기화 }); test("첫 번째 테스트", () => { mockFn(); expect(mockFn).toHaveBeenCalledTimes(1); expect(mockFn()).toBe("mocked value"); // 구현은 유지됨 }); test("두 번째 테스트", () => { // clearAllMocks 덕분에 호출 횟수가 0부터 시작 expect(mockFn).toHaveBeenCalledTimes(0); expect(mockFn()).toBe("mocked value"); // 구현은 여전히 유지 }); }); ``` ### `jest.resetAllMocks()` [jest.resetAllMocks() · Jest](https://jestjs.io/docs/jest-object#jestresetallmocks) > mock 함수를 완전히 초기화 => 호출 기록과 구현 모두가 삭제된다. mock 함수의 모든 상태를 초기화한다. 개별 Mock 함수에서 .mockReset()을 호출한 것과 동일한 결과. 정리되는 것: - clearAllMocks()에서 정리되는 모든 것들 - `mockReturnValue` 등으로 설정한 반환값 - `mockImplementation` 등으로 설정한 mock 구현체 (새로운 jest.fn() 으로 교체된다.) ```ts describe("resetAllMocks", () => { const mockFn = jest.fn(); afterEach(() => { jest.resetAllMocks(); }); test("첫 번째 테스트", () => { mockFn.mockReturnValue("first value"); expect(mockFn()).toBe("first value"); }); test("두 번째 테스트", () => { // resetAllMocks로 인해 구현도 초기화됨 expect(mockFn()).toBeUndefined(); // 기본 jest.fn() 동작 // 새로운 구현 설정 필요 mockFn.mockReturnValue("second value"); expect(mockFn()).toBe("second value"); }); }); ``` ### `jest.restoreAllMocks()` [jest.restoreAllMocks() · Jest](https://jestjs.io/docs/jest-object#jestrestoreallmocks) > spy를 원본 구현으로 복원. jest.spyOn() 으로 생성한 spy를 원본 구현으로 "복원" ```ts describe("restoreAllMocks", () => { const mockFn = jest.fn(); afterEach(() => { jest.restoreAllMocks(); // spy만 복원 }); test("Date.now spy 테스트", () => { const dateSpy = jest.spyOn(Date, "now").mockReturnValue(1234567890); mockFn.mockReturnValue("mocked value"); expect(Date.now()).toBe(1234567890); expect(dateSpy).toHaveBeenCalled(); expect(mockFn()).toBe("mocked value"); }); test("spy 복원 확인", () => { // restoreAllMocks로 인해 원본 Date.now로 복원됨 expect(typeof Date.now()).toBe("number"); expect(Date.now()).toBeGreaterThan(1000000000000); // mockFn은 여전히 mock 상태 + 초기화되지 않음 expect(mockFn()).toBe("mocked value"); expect(mockFn).toHaveBeenCalled(); }); }); ``` ### `mockFn.mockClear()` > 개별 mock 함수의 호출 기록만 삭제 ### `mockFn.mockReset()` > 개별 mock 함수를 완전히 초기화 (호출 기록 + 구현) ### `mockFn.mockRestore()` > jest.spyOn()으로 생성한 개별 spy를 원본 구현으로 복원 ## Module mock 정리 ### `jest.unmock(moduleName)` [jest.unmock(moduleName) · Jest](https://jestjs.io/docs/jest-object#jestunmockmodulename) > 특정 모듈의 mock을 해제한다. ```ts // math.ts export const add = (a: number, b: number): number => a + b; ``` ```ts // math.test.ts jest.mock("./math"); // 전체 모듈 mock describe("unmock", () => { test("mock된 상태", () => { const { add } = require("./math"); expect(add(2, 3)).toBeUndefined(); // mock된 상태 }); test("unmock 후 실제 구현 사용", () => { jest.unmock("./math"); // mock 해제 // 모듈 재로드 필요 jest.resetModules(); const { add } = require("./math"); expect(add(2, 3)).toBe(5); // 실제 구현 사용 }); }); ``` ### `jest.resetModules()` [jest.resetModules() · Jest](https://jestjs.io/docs/jest-object#jestresetmodules) > 모듈 레지스트리 (require로 부른 모든 모듈들의 캐시)를 전체 초기화 ```ts // counter.ts let count = 0; export const increment = () => ++count; export const getCount = () => count; ``` ```ts // counter.test.ts describe("resetModules 예제", () => { test("첫 번째 테스트", () => { const { increment, getCount } = require("./counter"); increment(); increment(); expect(getCount()).toBe(2); }); test("두 번째 테스트 - 모듈 캐시 유지", () => { const { increment, getCount } = require("./counter"); increment(); expect(getCount()).toBe(3); // 이전 테스트 영향 받음 }); test("세 번째 테스트 - 독립적 실행", () => { jest.resetModules(); // 모듈 캐시 초기화 // resetModules 덕분에 새로운 인스턴스 const { increment, getCount } = require("./counter"); increment(); expect(getCount()).toBe(1); // 이전 테스트 영향 없음 }); }); ``` ### `jest.isolateModules(fn)` [jest.isolateModules(fn) · Jest](https://jestjs.io/docs/jest-object#jestisolatemodulesfn) > 특정 모듈을 샌드박스 환경에서 격리해서 로드 ```ts test("격리된 환경에서 다른 설정 테스트", () => { let isolatedApp; jest.isolateModules(() => { // 격리된 환경에서 config 수정 const { setApiUrl } = require("./config"); setApiUrl("https://test.api.com"); // 격리된 환경에서 app 로드 isolatedApp = require("./app"); }); expect(isolatedApp.makeRequest()).toBe("Requesting: https://test.api.com"); // 격리 외부에서는 원본 config 유지 const { getApiUrl } = require("./config"); expect(getApiUrl()).toBe("https://api.example.com"); }); ```