bba278
bba278

Reputation: 419

Testing for a function/method call on click event inside a functional component

After a number of days hitting a wall, I understood that testing functional components with vue-test-utils causes some issues

To summarize, I am using Bootstrap-Vue's B-Button with a @click event on it that calls some function/method. When I try to run a test to understand whether the method is called, the test fails. However, when I swap the functional B-Buttonwith a <button> the test passes.

Here is JobSearch.vue component

<template>
  <b-input-group>
    <b-form-input
      class="mr-2 rounded-0"
      placeholder="Enter Search term..."
      id="input-keyword"
    />
<!--    <b-button-->
<!--      @click="searchJobs"-->
<!--      class="rounded-0 ml-2"-->
<!--      variant="primary"-->
<!--      id="reset-button"-->
<!--    >-->
<!--      Reset-->
<!--    </b-button>-->

    <button
      @click="resetFilter"
      class="rounded-0 ml-2"
      id="reset-button">
      Reset
    </button>
  </b-input-group>
</template>
<script>
export default {
  name: 'job-search-test',
  methods: {
    async searchJobs () {
      console.log('Calling Search Jobs from JobsSearchTest')
    },
    resetFilter () {
      console.log('Clicked On Reset')
    }
  },
  mounted () {
    // this.searchJobs()
  }
}
</script>

Here is JobSearch.spec.js

import { shallowMount, createLocalVue } from '@vue/test-utils'
import BootstrapVue from 'bootstrap-vue'
import JobSearchTest from '@/components/jobs/JobSearchTest'

const localVue = createLocalVue()
localVue.use(BootstrapVue)

describe('JobsSearchTest.vue', () => {
  it('should call searchJobs method when component is mounted', () => {
    let searchJobs = jest.fn()

    shallowMount(JobSearchTest, {
      methods: {
        searchJobs
      },
      localVue })
    expect(searchJobs).toHaveBeenCalledTimes(1)
  })

  it('should call resetFilter method on reset button click event', () => {
    let resetFilter = jest.fn()
    const wrapper = shallowMount(JobSearchTest, {
      methods: {
        resetFilter
      },
      localVue
    })
    expect(resetFilter).not.toHaveBeenCalled()
    wrapper.find('#reset-button').trigger('click')
    console.log(wrapper.find('#reset-button'))
    expect(resetFilter).toHaveBeenCalled()
  })
})

By commenting out the <b-button> part and commenting the <button> the test fails, however, it will be nice if it can pass since for this project we would like to use Bootstrap Vue.

Any ideas for a work around, which would not take away the value of the test? For example, according to an earlier question I asked, functional components don't operate well with directives, hence by using a non-functional stub the directive works fine, however, this takes away the value of the test.

Use more than one directive to add data attributes to components

Upvotes: 2

Views: 4493

Answers (1)

bba278
bba278

Reputation: 419

As far as I understood there are two answers to this.

When using shallowMount the functional components should be stubbed when creating the wrapper.

The other solution is to use mount. Shallow mount is really only good when only the component is tested in isolation. Here I am testing children... and since b-button is a child component... I need to bring it in

Upvotes: 3

Related Questions