Programing

TDD 중 Vue 인스턴스의 조롱 방법

c10106 2022. 3. 10. 21:56
반응형

TDD 중 Vue 인스턴스의 조롱 방법

나는 Vue 앱을 만들면서 TDD를 배우고 있고, 실패하는 단위 테스트를 만족시키기 위해 생산 코드만 쓸 수 있는 엄격한 법을 준수하려고 노력 중이다.나는 이 접근법을 정말 즐기고 있지만, 나는 Vue 인스턴스에 방법을 추가하고, 템플릿의 요소에서 이벤트가 발생할 때 그것들이 호출되었다는 것을 테스트하는 것과 관련하여 장애물에 부딪쳤다.

대리 방법을 조롱하면 결국 부르지 않게 된다는 점에서 부에 방법을 어떻게 조롱할 수 있을지에 대한 어떤 제안도 찾을 수 없다(제스트와 부에스트 테스트 유틸리티를 사용하고 있다).

나도 사이프러스를 사용하고 있어서 이 시험은 e2e로 채울 수 있지만 단위 시험으로 가능한 한 많이 채울 수 있었으면 좋겠어.

나는 Edd Yerburg의 "Testing Vue.js Applications"라는 책을 소유하고 있지만, 테스트 구성 요소 방법에 관한 섹션에서 그는 다음과 같이 간단히 언급한다.

종종 구성요소는 내부적으로 방법을 사용한다.예를 들어, 버튼을 클릭했을 때 콘솔에 로그인하려면 [...] 이러한 방법은 구성 요소 외부에서 사용할 수 있는 것이 아니라 개인 방법으로 생각할 수 있다.개인 방법은 구현 상세사항이기 때문에 직접 테스트는 작성하지 않는다.

이러한 접근방식은 TDD의 더 엄격한 법이 지켜지는 것을 분명히 허용하지 않는데, TDD 청교도들은 이것을 어떻게 처리할 것인가?

단추구성 요소.부에를 하다

<template>
    <button @click="method">Click me</button>
</template>

<script>
    export default: {
        methods: {
            method () {
                // Have I been called?
            }
        }
    }
</script>

버튼구성 요소.spec.js

it('will call the method when clicked', () => {
    const wrapper = shallowMount(ButtonComponent)
    const mockMethod = jest.fn()
    wrapper.vm.method = mockMethod

    const button = wrapper.find('button')
    button.vm.$emit('click')

    expect(mockMethod).toHaveBeenCalled()
    // Expected mock function to have been called, but it was not called
})

솔루션 1:jest.spyOn(Component.methods, 'METHOD_NAME')

장착하기 전에 구성 요소 방법을 조롱하는 데 사용할 수 있다.

import MyComponent from '@/components/MyComponent.vue'

describe('MyComponent', () => {
  it('click does something', async () => {
    const mockMethod = jest.spyOn(MyComponent.methods, 'doSomething')
    await shallowMount(MyComponent).find('button').trigger('click')
    expect(mockMethod).toHaveBeenCalled()
  })
})

솔루션 2: 조롱할 수 있는 별도의 파일로 방법 이동

공식적인 권고사항은 "하드 부품을 추출"하고, 제스트의 다양한 조롱 메커니즘을 사용하여 시험 대상 부품이 호출한 추상화된 모듈을 조롱하는 이다.

예를 들어, 다음을 검증하려면click-messages 호출:

  1. 이동click-핸들러의 본문을 공유 JavaScript 파일에 넣는다.
  2. 테스트 대상 구성 요소와 테스트에서 공유 모듈을 가져오십시오(두 경우 모두 동일한 가져오기 경로를 사용하십시오).
  3. 부르다jest.mock()공유 모듈의 내보낸 기능을 조롱한다.
  4. 테스트 제품군의 모의실험을 재설정하십시오.이것은 스위트룸에 여러 가지 테스트가 있을 때만 필요할 수 있다.
// @/components/MyComponent/utils.js
export function doSomething() { /*...*/ } //1️⃣

// @/components/MyComponent/MyComponent.vue (<script>)
import { doSomething } from '@/components/MyComponent/utils' //2️⃣

export default {
  methods: {
    onClick() {
      doSomething() //1️⃣
    }
  }
}

// @/test/MyComponent.spec.js
import { doSomething } from '@/components/MyComponent/utils' //2️⃣
jest.mock('@/components/MyComponent/utils') //3️⃣

describe('MyComponent', () => {
  beforeEach(() => doSomething.mockClear()) //4️⃣

  it('click does something', async () => {
    await shallowMount(MyComponent).find('button').trigger('click')
    expect(doSomething).toHaveBeenCalled()
  })
})

솔루션 3:setMethods()(v1.0 이전)

사용하다setMethods()구성 요소 메서드를 덮어쓰는 방법(v1.0 기준):

describe('MyComponent', () => {
  it('click does something', async () => {
    // Option A:
    const mockMethod = jest.fn()
    const wrapper = shallowMount(MyComponent)
    wrapper.setMethods({ doSomething: mockMethod })
    await wrapper.find('button').trigger('click')
    expect(mockMethod).toHaveBeenCalled()

    // Option B:
    const mockMethod = jest.fn()
    const wrapper = shallowMount(MyComponent, {
      methods: {
        doSomething: mockMethod
      }
    })
    await wrapper.find('button').trigger('click')
    expect(mockMethod).toHaveBeenCalled()
  })
})

데모를 하다

Tony19가 언급했듯이, SpyOn 방법을 사용하는 것은 너에게 효과가 있을 것이다.또한 괄호를 추가해야 함을 알게 되었다.()템플릿에 있는 방법에 대해 설명하십시오.나는 다음 파일들과 함께 시험을 통과하도록 했다.

단추구성 요소.부에를 하다

<template>
  <button @click="method()">Click me</button>
</template>

<script>
export default {
  methods: {
    method() {
      // Have I been called?
    }
  }
}
</script>

버튼구성 요소.spec.js

import ButtonComponent from '@/components/ButtonComponent'
import { shallowMount } from '@vue/test-utils'

it('will call the method when clicked', () => {
  const wrapper = shallowMount(ButtonComponent)
  const mockMethod = jest.spyOn(wrapper.vm, 'method')

  const button = wrapper.find('button')
  button.trigger('click')

  expect(mockMethod).toHaveBeenCalled()
  // passes
})

참조URL: https://stackoverflow.com/questions/53799460/mocking-methods-on-a-vue-instance-during-tdd

반응형