티스토리 뷰

상황

프로젝트 중, 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>

 

테스트 코드 수정 없이 문제가 해결되었다. 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
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
글 보관함