Jest 'toHaveBeenCalled' для событий клика работает только после двух кликов? (Тестирование приложения Vue) - PullRequest
0 голосов
/ 15 ноября 2018

Простой компонент:

<template>
  <div>
    <p>
      {{ count }}
    </p>
    <button @click="increment" data-test="increment">Increment</button>
  </div>
</template>
<script>
  export default {
    data () {
      return {
        count: 0
      }
    },
    methods: {
      increment () {
        this.count++
      }
    }
  }
</script>

И мой тест:

import TestExperiment from '@/components/TestExperiment'
import { createLocalVue, shallowMount } from '@vue/test-utils'

const localVue = createLocalVue()

describe('testexperiment.test.js', () => {
  const cmp = shallowMount(TestExperiment, {
    localVue
  })

  const increment = jest.spyOn(cmp.vm, 'increment')
  const incrementButton= cmp.find('[data-test="increment"]')

  test('clicking increment button calls increent', () => {

    expect(incrementButton.exists()).toBe(true)

    incrementButton.trigger('click')

    // Checking call here fails:
    // expect(increment).toHaveBeenCalled()

    // Function was still obviously called
    expect(cmp.vm.count).toBe(1)

    incrementButton.trigger('click')

    // Checking call here passes:
    expect(increment).toHaveBeenCalled()
  })

})

Как видите, я дважды нажимаю на кнопку incrementButton.

После первого вызова, если я проверю, был ли вызван метод increment, он возвращает false. Тем не менее, счет действительно увеличивается. После второго вызова он регистрирует, что он действительно был вызван (если я проверю, сколько раз он был вызван, он утверждает, что он был вызван один раз, даже если счетчик равен 2, очевидно, был увеличен в два раза).

Чего мне не хватает в работе Jest / Vue?

1 Ответ

0 голосов
/ 23 ноября 2018

Вам необходимо использовать метод Vue Test Utils setMethod:

const wrapper = mount(Foo)
const clickMethodStub = sinon.stub()

wrapper.setMethods({ clickMethod: clickMethodStub })
wrapper.find('button').trigger('click')

expect(clickMethodStub.called).toBe(true)

Причина, по которой он не работает в вашем примере, заключается в том, что элемент, по которому вы отправляете щелчокимеет оригинальный обработчик, созданный компонентом при его создании.

Он работает после двух вызовов trigger, так как первоначальный вызов вызывает повторное рендеринг, а обработчику исправленного элемента обновлен метод использования заглушки, добавленный в экземпляр.

...