Vue Test Utils 에서 mount 와 shallowMount 의 차이
Vue 에서 테스트 코드를 짜기 위해서 Vue Test Utils 를 사용하는데,
테스트 코드에서 Wrapper 를 만드는 메소드는 mount 와 shallowMount 두 가지가 있다.
크게 대단한 내용은 없지만 정리할 겸 둘의 차이를 알아보았다.
1. mount
Creates a Wrapper that contains the mounted and rendered Vue component.
공식 문서의 설명이다. 말 그대로 mounted 되고 렌더까지 된 뷰 컴포넌트를 생성한다.
여기서 중요한 점은, mount 메소드는 mount()를 한 컴포넌트 뿐만 아니라,
해당 컴포넌트의 자식 컴포넌트 까지도 렌더를 해버린다는 점이다.
간단한 예를 들어보겠다.
<template>
<div id="app">
<child-component message="Hello World">
</child-component>
</div>
</template>
<script>
import ChildComponent from "./ChildComponent"
export default {
name: "App",
components: {
ChildComponent
}
}
</script>
<template>
<div class="child">
<span>{{ message }}</span>
</div>
</template>
<script>
export default {
name: "ChildComponent",
props: {
message: {
type: String,
default: ''
}
}
}
</script>
위와 같은 부모 컴포넌트(App), 자식 컴포넌트(ChildComponent)가 있다고 가정하겠다.
App컴포넌트의 테스트 코드에서 mount() 를 사용한다면 아래와 같이 렌더링 된 자식 컴포넌트에 접근할 수 있다.
import { mount } from '@vue/test-utils'
import App from '@/App'
describe('Test for App', () => {
it('App이 message를 넘겨주면 ChildComponent는 해당 메세지를 렌더링한다.', () => {
const wrapper = mount(App)
expect(wrapper.find('.child > span').text()).toEqual('Hello World')
})
})
2. shallowMount
Like mount, it creates a Wrapper that contains the mounted and rendered Vue component, but with stubbed child components.
마운트와 기본적으로는 동일하지만, 딱 하나 큰 차이점이 있다.
"stubbed child components" 라는 말이 있는데,
대충 이해가 되듯 자식 컴포넌트들을 렌더링 하지 않는다는 의미이다.
따라서 위 테스트코드에서 mount 대신 shallowMount 를 사용한다면
find 메소드가 해당 엘리먼트를 찾지 못해서 에러가 발생할 것이다.
즉, ChildComponent 에 대한 테스트를 위해서는 ChildComponent 의 테스트파일이 별도로 존재해야한다.
정리
사실 회사에서나 개인프로젝트에서는 늘 그랬듯 shallowMount 만 해왔을 뿐
mount 와의 차이점을 제대로 본건 이번이 처음이다.
결과적으로 유닛 테스트를 할 때에는 shallowMount 를 하는 것이 일반적일 것 같다.
구글링을 통해 해외 개발자들의 의견들을 보니 대체로 일관적이다.
비록 mount 가 중첩된 컴포넌트들을 확인 할 수 있지만,
해당 자식 컴포넌트들에 대한 test가 따로 존재하는 것이 좋다고들 한다.