IT이야기

Sinon은 Vue 이벤트에 의해 트리거된 Vue 컴포넌트 메서드를 어떻게 감시합니까?

cyworld 2022. 7. 19. 21:09
반응형

Sinon은 Vue 이벤트에 의해 트리거된 Vue 컴포넌트 메서드를 어떻게 감시합니까?

문제를 설명하기 위해 수행한 기본 설정:

vue-cli 2.8.2를 사용하여 웹 팩 템플릿을 기반으로 새 프로젝트를 생성했습니다.vue init webpack vue-test-sinon-spy)는 vue-cli의 모든 기본값을 유지합니다(eslint를 디세블로 하는 것과 무관한 예외).

이 vue-cli 생성 프로젝트에서 수행된 변경 사항:

  1. Hello.vue의 h2 태그에 이벤트를 첨부했습니다.
<h2 @click="sayHello">Essential Links</h2>
  1. Hello 컴포넌트에 메서드를 추가했습니다.
<script>
export default {
  ...
  methods: {
    sayHello() {
      console.log('hello!')
    }
  }
}
</script>
  1. Hello.spec.js에 새로운 테스트를 추가했습니다.
describe('Hello.vue', () => {
  // ...

  it('should handle click on h2 tag', () => {
    const Constructor = Vue.extend(Hello)
    const vm = new Constructor().$mount()
    sinon.spy(vm, 'sayHello')

    // [A] if I run the line below, vm.sayHello.callCount will be 0 - not as expected
    vm.$el.querySelector('h2').click()

    // [B] if I run the line below, vm.sayHello.callCount will be 1 - as expected
    // vm.sayHello()

    // vm.sayHello.callCount will be 0 or 1, depending on
    //    what line I execute ([A] or [B]),
    //    even if in both cases sayHello method is really executed
    console.log('###', vm.sayHello.callCount)
  })
})

프로그래밍 방식으로 html 태그를 클릭할 때(사용)vm.$el.querySelector('h2').click()spy는 메서드의 실행을 캡처하지 않습니다.sayHello,따라서vm.sayHello.callCount0이 됩니다.내가 좋아하는 건 아니야.

하지만 제가 직접 전화를 걸면sayHello(사용)vm.sayHello()),vm.sayHello.callCount1이 됩니다.역시.

어떻게 하면 스파이에게 전화를 걸게 할 수 있을까요?sayHello(그래서vm.sayHello.callCounthtml 태그 클릭을 시뮬레이트 하는 경우는, 1이 됩니다.vm.$el.querySelector('h2').click()직접 호출하지 않음)sayHello(없음)vm.sayHello())?

고마워요.

여기서의 문제는 컴포넌트가 마운트되었을 때 콜백이 이벤트에 바인드된다는 것입니다.이게 어떻게 작동되는지는 잘 모르겠지만 이건 마치...sayHello클릭 이벤트 범위 내의 메서드.바인딩된 후에는 수정할 수 없습니다.

그 후 컴포넌트 메서드로 스파이를 만듭니다.그들은 똑같이 행동하지만 그렇지 않다.한 명은 스파이고 다른 한 명은 아니야

wrapper.vm.sayHello()메서드를 실행합니다(스파이)wrapper.find('h2').trigger('click')콜백을 실행합니다(스파이되지 않음).

마운트하기 전에 컴포넌트클래스에 스파이를 생성하면 인스턴스가 정상적으로 동작합니다.

it('should handle click on h2 tag - vue-test-utils + dummy click version', () =>     {
    const clickSpy = sinon.spy(Hello.methods, 'sayHello')
    const wrapper = mount(Hello)
    ...
})

(이것에 대한 Phil의 코멘트는 유닛 테스트의 유효한 사용이 아닙니다.)

해결 방법은 다음과 같습니다.

  1. vue-test-utils 설치:yarn add --dev https://github.com/vuejs/vue-test-utils(afaiu, vue-test-subs는 아직 정식 출시되지 않았습니다.)

  2. 더미 클릭 이벤트 트리거

이제 예상대로 실행되는 새 테스트를 추가할 수 있습니다.

describe('Hello.vue', () => {
  // ...
  it('should handle click on h2 tag - vue-test-utils + dummy click version', () => {
    const wrapper = mount(Hello)
    sinon.spy(wrapper.vm, 'sayHello')

    // trigger a dummy click event
    wrapper.find('h1').trigger('click')

    // [A] if I run the line below, vm.sayHello.callCount will be 1 - as expected
    wrapper.find('h2').trigger('click')

    // [B] if I run the line below, vm.sayHello.callCount will be 1 - as expected
    // wrapper.vm.sayHello()

    // vm.sayHello.callCount will be 1 in both [A] and [B] cases
    console.log('#####', wrapper.vm.sayHello.callCount)
  })
})

이 동작은 너무 이상해서 Vue가 2.x.x 프로젝트라기보다 애완용 프로젝트처럼 보이게 되어 제가 뭔가 오해를 했을 수도 있습니다.

언급URL : https://stackoverflow.com/questions/45787562/how-to-sinon-spy-a-vue-component-method-triggered-by-a-vue-event

반응형