반응형
SMALL
React에서는 react-dom/test-utils, testing-library/react, enzyme 등 유닛 테스트를 실행할 수 있는 방법이 있습니다.
반면 Vue의 경우, 리액트에서 인기인 testing-library의 Vue 버전인 testing-library/vue가 있긴 하지만, 주로 vue-test-utils를 사용하는 것 같아, vue-test-utils로 적용해보았습니다.
테스트 전, 테스트를 구성을 하도록 하겠습니다.
// jest.config.jsmodule.exports = {
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
moduleFileExtensions: ['js', 'jsx', 'json', 'vue', 'ts', 'tsx'],
moduleNameMapper: { '^@/(.*)$': '<rootDir>/src/$1' },
testMatch: ['**/__tests__/*.[jt]s?(x)'],
setupFiles: ['<rootDir>/src/tests/setup.ts'],
};
- setupFiles는 테스트 시, 글로벌하게 적용될 라이브러리 등을 추가할 수 있는 파일을 참조해놓은 속성입니다. 저는 src/tests/setup.ts 파일에서 구성했습니다.
- moduleFileExtensions는 테스트 파일 작성 시, 사용할 확장자명을 적어두었습니다.
- testMatch는 테스트를 돌릴 때, 인식할 파일의 위치와 확장자명을 정해두는 곳입니다.
setupFiles에서 지정해놓은 파일에서 테스트 시, ‘@vue/composition-api’를 사용할 수 있도록 구성하도록 하겠습니다.
setup.ts에서 compositionAPI를 Vue.use를 하지 않는다면, 테스트를 돌릴 때 ref, reactive로 정해둔 data를 이용할 수 없어서 테스트가 실패할 것입니다.
// src/tests/setup.ts
import Vue from 'vue';
import compositionAPI from '@vue/composition-api';Vue.use(compositionAPI);
다음은 해당 컴포넌트를 테스트 하도록 하겠습니다.
// src/views/ConsultingPage/ConsultingPage.vue<template>
<div class="card-view-wrapper">
<consulting-card-view
:key="card.id"
v-for="card in cards"
:card="card"
></consulting-card-view>
</div>
</template>
<script lang="ts">
import { URL_LISTS } from '@/constants/constants';
import { onMounted, ref } from '@vue/composition-api';
import ConsultingCardView from './ConsultingCardView.vue';
import { IConsultingCard } from '../type';export default {
components: { 'consulting-card-view': ConsultingCardView },
setup() {
const cards = ref<IConsultingCard[]>([]);onMounted(() => {
cards.value = URL_LISTS;
});return { cards };
},
};
</script>
다음은 테스트 파일입니다
// src/views/ConsultingPage/__tests__/ConsultingPage.spec.tsximport { mount } from '@vue/test-utils';
import ConsultingPage from '../ConsultingPage.vue';describe('상담 페이지', () => {
it('상담 카드가 잘 렌더링 됐는지 확인', () => {
const cards = [
{
image:
'<https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80>',
name: '이기원',
currentJob: '중앙대학교 사회복지학부 3학년',
mainSection: '학교폭력 상담',
price: 3000,
evaluationIndex: 9.0,
},
]; const wrapper = mount(ConsultingPage, {
data() {
return { cards };
},
});
console.log(wrapper.html());expect(wrapper.attributes('class')).toBe('card-view-wrapper');
});
});
mount 시, data를 넣지 않을 경우, ConsultingPage에서 v-for를 하고 있는 consulting-card-view 컴포넌트는 wrapper.html()로 DOM을 볼 경우, mount가 되지 않는 것을 확인할 수 있습니다
- 테스트에서 mount 시, data를 넣지 않은 경우, 테스트에서 인식하는 ConsultingPage의 DOM
<div class="card-view-wrapper"></div>
- 테스트에서 mount 시, data를 넣은 경우, 테스트에서 인식하는 ConsultingPage의 DOM
<div class="card-view-wrapper">
<div class="card-container">
<div class="card-view-box"><img src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80" alt="card-view-image" class="card-view-image">
<div class="teacher-info-box">
<p class="teacher-name-label">
이기원 <span class="teacher-label">선생님</span></p>
<p class="current-job-label">중앙대학교 사회복지학부 3학년</p>
<div class="section-box">
<p class="section-label">주요분야</p>
<p>학교폭력 상담</p>
</div>
<div class="price-box">
<p>3000</p>
<p>9 / 10.0</p>
</div>
</div>
<v-icon></v-icon>
</div>
</div>
</div>
반응형
LIST
'Vue' 카테고리의 다른 글
Pinia의 state를 그대로 읽어들이기 (0) | 2022.06.21 |
---|---|
[IAM] 사용자, 그룹, 정책 - 사용자 Alias 만들기 (0) | 2022.06.19 |
setup에서 CSS Module에 접근하는 방법 (0) | 2022.06.18 |
ref를 이용해서 resize 하기 (0) | 2022.06.18 |
버튼 컴포넌트에서 상위 컴포넌트의 함수 실행시키는 방법 - emit (0) | 2022.06.18 |