ResizeObserver Mock (Vitest, ES Module 환경)
vi.mock() 은 파일 맨 위로 끌어올려져 바깥 변수를 못 본다 — 그래서 vi.hoisted() 로 모킹 함수를 미리 선언해 넘긴다.1
import { vi } from 'vitest'
const { mockResizeObserver, MockResizeObserver } = vi.hoisted(() => {
let observers: { callback: ResizeObserverCallback; observer: any }[] = []
// new 로 불리므로 화살표 함수가 아니라 function — 화살표면 "is not a constructor"
const MockResizeObserver = vi.fn().mockImplementation(function (callback) {
const observer = {
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
}
observers.push({ callback, observer })
return observer
})
return {
MockResizeObserver,
mockResizeObserver: {
triggerResize: (entries: ResizeObserverEntry[], index = 0) => {
observers[index]?.callback(entries, observers[index].observer)
},
reset: () => {
observers = []
},
},
}
})
vi.mock('resize-observer-polyfill', () => ({ default: MockResizeObserver }))
// 테스트에서 사용
beforeEach(() => mockResizeObserver.reset())
it('should handle resize', () => {
const mockEntry = {
target: document.createElement('div'),
contentRect: { width: 100 },
}
mockResizeObserver.triggerResize([mockEntry])
})
핵심: ES Module에서는 vi.hoisted() 필수. 여러 observer는 배열로 추적.
Footnotes
-
vi.mock - Vitest: “The call to
vi.mockis hoisted, so it doesn’t matter where you call it. … If you need to reference some variables outside of its scope, you can define them insidevi.hoistedand reference them insidevi.mock.” / vi.spyOn: “If you provide an arrow function, you will get<anonymous> is not a constructorerror when the mock is called.” ↩