티스토리 뷰
상황
프로젝트 중, Navigation의 버튼에 따라 routing이 필요했다.
TDD 방식을 적용시켜 Jest로 route에 관련된 테스트 코드를 미리 작성했고, 그에 따라 Navbar.vue파일에 Navigation Bar를 제작하였다.
코드는 다음과 같이 제작하였다.
<!-- Navbar.vue -->
<template>
<div id='navigation' class='position-fixed flex'>
<div v-for='m in menu' :key='m.name'
:class='isSelected(m.select)' @click='selectMenu(m.route)'
data-test='`nav-button-${m.route}`' >
<font-awesome-icon :icon='m.icon' />
<p class='navigation-btn-title' data-test='nav-button-title'>{{ m.name }}</p>
</div>
</div>
</template>
<script>
export default {
methods: {
selectMenu(menuName) {
this.menu[this.nowSelected].select = false;
this.menu[menuName].select = true;
this.nowSelected = menuName;
this.$router.push({ name: menuName });
},
isSelected(select) {
return select ? 'navigation-btn flex selectedMenu' : 'navigation-btn flex';
},
},
created() {
this.selectMenu(window.location.href.split('/')[3]);
},
};
</script>
Navbar를 사용하면서 사용자가 버튼을 클릭했을 때 버튼의 색상도 함께 변화시키기 위해
Click 이벤트로 selectMenu를 발생시켰고, select Menu 내부에서 해당 페이지로 넘어가게끔 코드를 작성했다.
beforeEach(() => {
wrapperApp = mount(App, {
global: {
plugins: [router],
stubs: [routes],
},
});
});
it('routing to Cart', async () => {
router.push('/');
await router.isReady();
await wrapperApp.find('[data-test="nav-button-cart"]').trigger('click');
await flushPromises();
expect(wrapperApp.findComponent(Cart).exists()).toBeTruthy();
});
테스트 코드는 공식문서를 바탕으로 작성했고, 실제 Router를 시켜서 테스트하였다.
Navbar를 포함하고 있는 App을 mount 하고, 버튼을 trigger 했을 때 적절한 컴포넌트가 App 내부에 표시되는지 테스트해주었다.
에러
1. Click이후에 select 값을 처리해주지 못하고 있어 내부 데이터와 method들을 일부 mocking 해주어야 한다고 판단했다.
2. 1번 에러를 해결하기 위해 내부 메서드를 mocking해준 후 발생한 에러로, 비동기 함수를 직접 호출해서 발생하는 문제라고 한다.
try() ~ catch()를 사용하면 해결할 수 있다는 자료를 발견했다. (참고: https://stackoverflow.com/questions/70283416/jest-error-on-node-16-err-unhandled-rejection )
해결방법
테스트 코드를 여러 수정해보기도 했지만,
selectMenu 메소드 자체가 하나의 메소드 내에 두 가지 작업을 처리( 아이콘 색상변경, 페이지 이동) 하고 있다는 생각이 들어서, 두 작업을 분리해주었다. 메서드 내에서는 아이콘 색상 변경만 하고, 페이지 이동은 기존 프로그래밍 방식에서 <router-link :to="'>를 사용해 주었다.
// Navbar.vue
<template>
<div id='navigation' class='position-fixed flex'>
<router-link v-for='m in menu' :key='m.name'
:class='isSelected(m.select)' :to='`/${m.route}`' @click='selectMenu(m.route)'
:data-test='`nav-button-${m.route}`' >
<font-awesome-icon :icon='m.icon' />
<p class='navigation-btn-title' data-test='nav-button-title'>{{ m.name }}</p>
</router-link>
</div>
</template>
<script>
export default {
methods: {
selectMenu(menuName) {
this.menu[this.nowSelected].select = false;
this.menu[menuName].select = true;
this.nowSelected = menuName;
},
isSelected(select) {
return select ? 'navigation-btn flex selectedMenu' : 'navigation-btn flex';
},
},
created() {
this.selectMenu(window.location.href.split('/')[3]);
},
};
</script>
테스트 코드 수정 없이 문제가 해결되었다.
'Errors' 카테고리의 다른 글
[ISSUES] Axios Post 요청시 401: Unauthorized 에러 발생 이슈 (0) | 2022.03.27 |
---|---|
맥 M1 SASS 에러 해결 방법 (0) | 2022.02.18 |
Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style' (0) | 2022.01.06 |
React 페이지 전환시 Reload 이슈 (5) | 2021.11.12 |
[JavaScript] JS를 사용한 스크래핑 (0) | 2021.10.06 |
- Total
- Today
- Yesterday
- Preloading
- SOAP API
- reactrouter
- GraphQL
- js
- redux-thunk
- Transpiler
- bundler
- React.memo
- webpack
- 파이썬
- Vue.js
- 백준
- python
- TypeScript
- clean code
- 문제풀이
- Vue
- 프로그래머스
- programmers
- SPA
- React
- redux
- 알고리즘
- Repository Pattern
- error
- 상호평가
- AxiosInterceptor
- Vuex
- v-for
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |