์ฌ์ด๋ ํ๋ก์ ํธ๋ฅผ ์ค์ํ๋ค๊ฐ ํ ์คํธ์ฝ๋์ ๊ด์ฌ์ ๊ฐ๊ฒ ๋์๋ค.
Vue์์๋ Jest ํ๋ ์์ํฌ๋ฅผ ์ถ์ฒํ์๋ค. ๊ทธ๋์ ๋์ ์ฌ์ด๋ ํ๋ก์ ํธ์์
์ด๋ป๊ฒ ํ ์คํธ์ฝ๋๋ฅผ ์์ฑํ๋์ง ์ ๊ณ ์ ํ๋ค.์ฐธ๊ณ ๋ก Jest ์ธํ ์ ๋ํด์๋ ์ ์ง๋ชปํ์๋ค. ์ถํ์ ์ ์ ์์ ์ด๋ค.
Vuetify,Vue,Jest
"Board" ์ปดํผ๋ํธ ๊ตฌ์กฐ๋ ์๋์ ๊ฐ๋ค.
์ฌ๊ธฐ์ ๋๊ฐ์ง ์ปดํผ๋ํธ๋ฅผ ํ ์คํธ ํ๊ณ ์ ํ๋ค. "BoardSearchBox.vue", "BoardList.vue" ๊ฐ ํ ์คํธํ ๋์์ด๋ค.
import Vuetify from 'vuetify';
import Vuex from 'vuex';
import VueRouter from 'vue-router';
import { shallowMount, createLocalVue, mount } from '@vue/test-utils';
import BoardSearchBox from 'root/components/board/BoardSearchBox';
import Board from 'root/view/board/Board';
import BoardCreate from 'root/view/board/BoardCreate';
import { boardStoreMock } from 'root/components/board/tests/mockStore/boardStoreMock';
import routes from 'root/routes/routes';
const localVue = createLocalVue();
localVue.use(Vuex);
localVue.use(VueRouter);
const store = new Vuex.Store({
modules: {
boardStore: boardStoreMock,
},
});
describe('BoardSearchBox ํ
์คํธ', () => {
let vuetify;
let wrapper;
let boardWrapper;
let router;
beforeEach(() => {
vuetify = new Vuetify();
router = new VueRouter({ routes });
wrapper = shallowMount(BoardSearchBox, {
vuetify,
localVue,
store,
});
boardWrapper = mount(Board, {
localVue,
router,
});
});
test('์ ๋ชฉ์ ์
๋ ฅํ๋ฉด id๊ฐ title์ธ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ค.', () => {
wrapper.find('#title').vm.$emit('input', 'CHOI');
expect(wrapper.find('#title')._emittedByOrder[0].args[0]).toBe('CHOI');
});
test('์์ฑ์๋ฅผ ์
๋ ฅํ๋ฉด id๊ฐ writer์ธ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ค.', () => {
wrapper.find('#writer').vm.$emit('input', '์ต๋๊ฑด');
expect(wrapper.find('#writer')._emittedByOrder[0].args[0]).toBe('์ต๋๊ฑด');
});
test('์ ๋ชฉ๊ณผ ์์ฑ์๋ฅผ ์
๋ ฅ ํ BoardStore์์ AC_BOARD_LIST๋ฅผ ํธ์ถํ๋ค.', async () => {
wrapper.find('#searchBtn').vm.$emit('click');
await wrapper.vm.$nextTick();
expect(boardStoreMock.actions.AC_BOARD_LIST).toHaveBeenCalled();
});
test('์ ๊ท ๋ฒํผ์ ๋๋ฅด๋ฉด BoardCreate๋ก ์ด๋ํ๋ค', async () => {
wrapper.find('#createBoard').vm.$emit('click');
router.push('/main/board/create');
await boardWrapper.vm.$nextTick();
expect(boardWrapper.findComponent(BoardCreate).exists()).toBe(true);
});
});
๋จผ์ "BoardSearchBox"๋ง ํ ์คํธ ํ๊ธฐ ๋๋ฌธ์ Vue์ ํ์ํ ๊ฒ๋ค์ ์ฌ์ฉํ๊ธฐ ์ํด "createLocalVue"๋ฅผ ์ฌ์ฉํ์๋ค.
์ฌ๊ธฐ์ ์ธํ ํ๋ ๋ถ๋ถ์ ์ค๋ช ํ๋ฉด ๋ด์ฉ์ด ๊ธธ์ด์ง๋ฏ๋ก ์๋ต ํ๊ฒ ๋ค.
"test(('ํ ์คํธ ํ ๋ด์ฉ')=>{ ํ ์คํธ ๋ก์ง })"
์ฌ๊ธฐ์ ์ค์ ํฌ์ธํธ๋ ํ๋ฉด์ ์ ๋ ฅํ์ ๋ v-text-field ๊ฐ์ด ๋ณ๊ฒฝ๋๋์ง ํ์ธํ๋ ๊ฒ์ด๋ค. test์ฝ๋๋ ์๋์ ๊ฐ๋ค.
test('์ ๋ชฉ์ ์
๋ ฅํ๋ฉด id๊ฐ title์ธ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ค.', () => {
wrapper.find('#title').vm.$emit('input', 'CHOI');
expect(wrapper.find('#title')._emittedByOrder[0].args[0]).toBe('CHOI');
});
1๋ฒ๊ณผ ๋์๊ฐ๋ ๋ก์ง์ ๊ฐ๋ค.
test('์์ฑ์๋ฅผ ์
๋ ฅํ๋ฉด id๊ฐ writer์ธ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ค.', () => {
wrapper.find('#writer').vm.$emit('input', 'ํ๊ธธ๋');
expect(wrapper.find('#writer')._emittedByOrder[0].args[0]).toBe('ํ๊ธธ๋');
});
์ฌ๊ธฐ์๋ Vuex์ BoardStore๋ชจ๋ ์์ AC_BOARD_LIST๋ฅผ ํธ์ถํด์ผ ํ๋ค.
ํ์ง๋ง AC_BOARD_LIST๋ฅผ ๋ฐฑ์๋์์ ํต์ ์ด ํ์ํ ์์ ์ด๋ค. ํ์ง๋ง ์ฌ๊ธฐ์๋ AC_BOARD_LIST๋ฅผ ํธ์ถํ๋ค๋ ๊ฒ์ด ์ค์ํ๋ค. ๊ทธ๋์ mock์ ํ์ฉํ์๋ค.
boardStoreMock ๋ง๋ค์์ผ๋ฉฐ ์ด๊ฒ์ ๊ฐ์ง BoardStore ๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
//boardStoreMock.js
const state = {
search: {
title: '',
writer: '',
page: 1,
itemPerPage: 5,
},
};
const boardStoreMock = {
state,
getters: {
GE_SEARCH() {
return state.search;
},
},
mutations: {
MU_SEARCH: jest.fn(),
},
actions: {
AC_BOARD_LIST: jest.fn(),
},
namespaced: true,
};
export { boardStoreMock };
์๋ ์ฝ๋๊ฐ AC_BOARD_LIST๋ฅผ ํธ์ถํ๋์ง ํ์ธํ๋ ์ฝ๋์ด๋ค.
test('์ ๋ชฉ๊ณผ ์์ฑ์๋ฅผ ์
๋ ฅ ํ BoardStore์์ AC_BOARD_LIST๋ฅผ ํธ์ถํ๋ค.', async () => {
wrapper.find('#searchBtn').vm.$emit('click');
await wrapper.vm.$nextTick();
expect(boardStoreMock.actions.AC_BOARD_LIST).toHaveBeenCalled();
});
์ฌ๊ธฐ์๋ ์ ๊ท ๋ฒํผ์ ๋๋ฅด๋ฉด ํ๋ฉด์ด ๋ฐ๋์ด์ผ ํ๋ค. ์ด ๋ง์ ํํํ๋ฉด ์๋์ ๊ฐ๋ค.
BoardList => BoardCreate๋ก router-view๊ฐ ๋ฐ๋์ด์ผ ํ๋ค.
๊ทธ๋ฌ๊ธฐ ์ํด์๋ ๋๊ฐ์ง๊ฐ ํ์ํ๋ค. Board.vue,BoardCreate.vue
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ์์ "ํฌ์ธํธ"๋ BoardCreate๊ฐ ํ๋ฉด์ด ์กด์ฌํ๋์ง๋ง ํ๋จํ๋ฉด ๋๋ค.
.
.
.
import Board from 'root/view/board/Board';
import BoardCreate from 'root/view/board/BoardCreate';
.
.
.
import VueRouter from 'vue-router';
.
.
.
const localVue = createLocalVue();
localVue.use(VueRouter);
import routes from 'root/routes/routes';
.
.
.
describe('BoardSearchBox ํ
์คํธ', () => {
.
.
let router;
let boardWrapper;
beforeEach(() => {
router = new VueRouter({ routes });
wrapper = shallowMount(BoardSearchBox, {
router,
});
boardWrapper = mount(Board, {
router,
});
});
})
jest.mock('root/view/board/BoardCreate', () => ({
name: 'boardCreate',
render: h => h('div'),
}));
describe('BoardSearchBox ํ
์คํธ', () => {
.
.
.
.
})
test('์ ๊ท ๋ฒํผ์ ๋๋ฅด๋ฉด BoardCreate๋ก ์ด๋ํ๋ค', async () => {
wrapper.find('#createBoard').vm.$emit('click');
router.push('/main/board/create');
await boardWrapper.vm.$nextTick();
expect(boardWrapper.findComponent(BoardCreate).exists()).toBe(true);
});
์์ง๊น์ง ๋ถ์กฑํ ๋ถ๋ถ๋ ๋ง๊ณ ๋ณด์ํ ๋ถ๋ถ๋ ๋ง์ผ๋ฉฐ ๋ค์์๋ BoardList ์ปดํผ๋ํธ๋ฅผ ํ ์คํธํ๊ณ ์ ํ๋ค.