Vue 3 테스트
테스트 주의사항
컴포저블을 목업(mock)하는 경우의 ref 관리
Vue 3 컴포저블을 테스트하는 일반적인 패턴은 이러한 파일들이 반환하는 ref
또는 computed
값을 목업하는 것입니다.
다음과 같은 데모 컴포저블을 고려해봅시다:
export const useCounter = () => {
const counter = ref(1)
const increase = () => { counter.value += 1 }
return { counter, increase }
}
현재 이러한 컴포저블을 사용하고 카운터를 노출하는 컴포넌트가 있다면 해당 기능을 포함하는 테스트를 작성하고 싶을 것입니다. 이러한 간단한 예제와 같은 경우, 컴포저블을 전혀 목업하지 않고도 통과할 수 있지만, Tanstack Query 래퍼나 Apollo 래퍼와 같이 더 복잡한 기능의 경우 jest.mock
을 활용해야 할 수도 있습니다.
이러한 경우에는 테스트 파일에서 컴포저블을 목업해야 합니다:
<script setup>
const { counter, increase } = useCounter()
</script>
<template>
<p>매우 유용한 카운터: {{ counter }}</p>
<button @click="increase">+</button>
</template>
import { ref } from 'vue'
import { useCounter } from '~/composables/useCounter'
jest.mock('~/composables/useCounter')
describe('MyComponent', () => {
const increaseMock = jest.fn()
const counter = ref(1)
beforeEach(() => {
useCounter.mockReturnValue({
increase: increaseMock,
counter
})
})
describe('카운터가 2 일 때', () => {
beforeEach(() => {
counter.value = 2
createComponent()
})
it('...', () => {})
})
it('기본값은 1 이어야 합니다', () => {
createComponent()
expect(findSuperUsefulCounter().text()).toBe(1)
// 실패
})
})
위의 예에서 볼 수 있듯이, 컴포저블에 의해 반환되는 함수와 counter
ref의 목업을 같이 생성하고 있지만, 매우 중요한 단계가 누락된 것입니다.
counter
상수는 ref
이며, 따라서 매번 우리가 이를 수정할 때마다 할당한 값이 유지됩니다. 위의 예에서 두 번째 it
블록은 이전 테스트 중 어느 것에서든 할당된 값이 유지될 것이므로 실패할 것입니다.
이 문제를 해결하고 권장 사항은 가장 상위 수준의 beforeEach
블록에서 항상 ref
를 재설정하는 것입니다.
import { ref } from 'vue'
import { useCounter } from '~/composables/useCounter'
jest.mock('~/composables/useCounter')
describe('MyComponent', () => {
const increaseMock = jest.fn()
// 더욱 신중하게하기 위해 `undefined`로 초기화할 수 있습니다
const counter = ref(undefined)
beforeEach(() => {
counter.value = 1
useCounter.mockReturnValue({
increase: increaseMock,
counter
})
})
describe('카운터가 2 일 때', () => {
beforeEach(() => {
counter.value = 2
createComponent()
})
it('...', () => {})
})
it('기본값은 1 이어야 합니다', () => {
createComponent()
expect(findSuperUsefulCounter().text()).toBe(1)
// 통과
})
})