본문 바로가기
Vue

🍋 vue jest 사이드로 시작하면서 배운것들

by frontChoi 2023. 8. 20.
반응형

※ 금주는 공휴일 및 연차로 인하여 회고를 쓰지 않습니다.

 

 

🥯 vue jest 하면서 배운것

세팅에 관한것은 여기에 참조를 부탁드립니다.

 

  • describe
  • test
  • shallMount, mount
  • emit 테스트(자식컴퍼넌트)
  • emit 테스트(부모컴퍼넌트)
  • triggers events - click
  • triggers events - key event
  • mock
  • axios spyOn

 

 

🍌 Describe

단위테스트의 그룹을 묶어둔것. 여기서는 한개의 Component 단위로 묶어서 테스트를 실시하였다.

describe('Helloworld.vue 테스트', () => {

});

 

🥯 test

단위테스트의 그룹에서, 최소 단위의 테스트를 작성

describe('Helloworld.vue 테스트', () => {
  test('테스트1', () => {

  });
});

 

🍆  shallMount, mount

shallMount는 하위 컴퍼넌트까지 렌더링 하지않는다. mount는 하위 컴퍼넌트까지 렌더링 한다.

 

shallMount 결과

<div>
  <button>클릭</button>
  <child-component-stub></child-component-stub>
</div>

mount결과

<div>
  <button>클릭</button>
  <div>
    childComponent
  </div>
</div>

🍳 emit 테스트(자식컴퍼넌트)

vue 파일

<template>
  <div>
    childComponent
  </div>
</template>
<script>
export default {
  emits: ["callemit"],
  data() {
    return {

    }
  },
  methods: {
    method1() {
      this.$emit('callemit', 123)
    }
  }
}
</script>
<style scoped></style>

 

emit 테스트 파일

callemit : 호출여부 확인

callemit.length : 몇번 호출되었는지 확인

callemit[index] : index번째의 어떤 인자 들어갔는지 확인

import { shallowMount } from "@vue/test-utils";
import ChildComponent from "@/components/ChildComponent.vue";
describe('ChildComponent Testing', () => {
  test('Emit을 테스트한다.', () => {
    const wrapper = shallowMount(ChildComponent);
    wrapper.vm.$emit('callemit', 123);
    // assert event has been emitted
    expect(wrapper.emitted().callemit).toBeTruthy();
    // assert event count
    expect(wrapper.emitted().callemit.length).toBe(1)

    // assert event payload
    expect(wrapper.emitted().callemit[0]).toEqual([123]);
  });
});

🍠 emit 테스트(부모컴퍼넌트)

<template>
  <div>
    <button>클릭</button>
    <child-component @callemit="onCallEmit" />
    <p v-if="emitted">Emitted!</p>
  </div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
  components: {
    'child-component': ChildComponent
  },
  data() {
    return {
      emitted: false
    }
  },
  methods: {
    onCallEmit() {
      this.emitted = true;
    }
  }
}
</script>
<style scoped></style>
import { mount, shallowMount } from "@vue/test-utils";
import HelloWorld from "@/components/HelloWorld.vue";
import ChildComponent from "@/components/ChildComponent.vue";
describe('Helloworld.vue 테스트', () => {
  test("ChildComponent으로부터 callemit 함수 받기", async () => {
    const wrapper = mount(HelloWorld);
    wrapper.findComponent(ChildComponent).vm.$emit('callemit');
    await wrapper.vm.$nextTick()
    expect(wrapper.html()).toContain('Emitted')
  })
});

🍤triggers events - click

마우스 클릭 할 경우 발생시키는 이벤트이다.

trigger에 발생시키고자 하는 이벤트를 넣어준다.

test('버튼을 클릭할 경우 2배를 곱한다.', async () => {
    const wrapper = shallowMount(KeyDownComponent);
    wrapper.vm.quantity = 4;
    const btn = wrapper.find('#btn');
    await btn.trigger('click'); //click말고 다양한 이벤트가 나올수 있다.
    expect(wrapper.vm.quantity).toBe(8);
  });

🍙triggers events - key event

키보드 누를  경우 발생시키는 이벤트이다.

Keyboard:KEY_DOWN

test('방향키 아래 버튼 누를 경우 값을 감소시킨다.', async () => {
    const wrapper = shallowMount(KeyDownComponent);
    wrapper.vm.quantity = 4;
    const input = wrapper.find('input');
    await input.trigger('keydown.down');
    expect(wrapper.vm.quantity).toBe(3);
  });

Keyboard:KEY_UP

 test('방향키 위 버튼 누를 경우 값을 증가시킨다.', async () => {
    const wrapper = shallowMount(KeyDownComponent);
    const input = wrapper.find('input');
    await input.trigger('keydown.up');
    expect(wrapper.vm.quantity).toBe(1);
  });

Keyboard:ESCAPE

test("Esc 누를 경우 값을 초기화 시켜준다.", async () => {
    const wrapper = shallowMount(KeyDownComponent);
    wrapper.vm.quantity = 20;
    const input = wrapper.find('input');
    await input.trigger("keydown.esc");
    expect(wrapper.vm.quantity).toBe(0)
  });

🍦mock

외부에 의존적인 부분이 존재할때, mock을 이용하는 것이며, 즉 가짜로 구현하여 대체한다.

//foreach.js
export function forEach(items, callback) {
  for (let index = 0; index < items.length; index++) {
    callback(items[index]);
  }
}

 

//foreach.spec.js
import { forEach } from '../../foreach';
const mockCallBack = jest.fn(x => 42 + x);

describe('ForEach mock testing', () => {
  test('test1', async () => {
    forEach([0, 1], mockCallBack);

    //mockCallBack 몇번 호출됐는지 확인
    expect(mockCallBack.mock.calls).toHaveLength(2);

    //매개변수 첫번째 값 확인
    expect(mockCallBack.mock.calls[0][0]).toBe(0);

    //매개변수 2번째 값 확인
    expect(mockCallBack.mock.calls[1][0]).toBe(1);

    //mockCallBack의 리턴된 값 확인
    expect(mockCallBack.mock.results[0].value).toBe(42)

  });
})

🥗axios spyOn

실제 API를 사용하면 네트워크 비용이 들기때문에, axios를 가짜로 만들어처리한다.

import { shallowMount } from "@vue/test-utils";
import AxiosPracticeComponent from "@/components/AxiosPracticeComponent.vue";
import axios from "axios";
describe('Axios 컴퍼넌트 테스팅', () => {
  test('버튼 클릭', async () => {
    const mockPostList = [
      { id: 1, title: 'title1' },
      { id: 2, title: 'title2' }
    ]
    //spyOn을 통해 mockResolvedValue사용하여 가짜 결과값을 리턴해준다.
    jest.spyOn(axios, 'get').mockResolvedValue(mockPostList)
    const wrapper = shallowMount(AxiosPracticeComponent);
    const btn = wrapper.find('#btn');
    await btn.trigger('click');

    expect(axios.get).toHaveBeenCalledTimes(1);
    expect(axios.get).toHaveBeenCalledWith('/api/posts');

    const posts = wrapper.findAll('[data-test="post"]');
    expect(posts).toHaveLength(2);

    expect(posts.at(0).text()).toContain('title1')
    expect(posts.at(1).text()).toContain('title2')
  });
});
반응형

'Vue' 카테고리의 다른 글

🫢 husky와 eslint 적용  (0) 2024.05.03
🍳 HOC사용하여 로직 공통화 시키기  (0) 2023.11.05
🏰 vue2 jest 환경세팅  (0) 2023.08.09
props으로 함수 받기  (0) 2023.07.23
👀 vscode 에서 EditorConfig 쓰기  (0) 2023.06.02

댓글