Examining the execution of a function/method when a click event occurs within a functional component

It took me a while to realize that testing functional components with vue-test-utils can present some challenges

In my case, I am utilizing Bootstrap-Vue's B-Button with a @click event that calls a function/method. When I attempt to test whether the method is being called, the test fails. However, if I switch the functional B-Button with a regular <button>, the test passes.

Below is the code snippet for the 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>

And here is the content of 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()
  })
})

I have noticed that by switching between using <b-button> and <button>, the test outcome changes. Is there a way to keep the tests consistent without compromising the use of Bootstrap Vue for this project?

If you have any ideas or workarounds that could solve this issue without devaluing the test results, please share them. For instance, in a previous query, it was mentioned that functional components do not always work well with directives. Therefore, using a non-functional stub may resolve the directive issue but at the expense of accurate testing.

Use more than one directive to add data attributes to components

Answer №1

From my understanding, there are two options to consider in this scenario.

When utilizing the shallowMount method, it is necessary to stub the functional components when creating the wrapper.

Alternatively, one can opt for using the mount method instead. Shallow mount proves most effective when solely testing the component in isolation. In this case, I am testing child components such as b-button, hence the need to include it.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the correct way to apply a concatenated element id when using the .click() function in

Having an issue with assigning buttons to input boxes in a loop. When using concatenated element IDs with the .click() method, the buttons won't click for some reason. The following code works: document.getElementById("streamInput1") .addEventLi ...

Trouble Loading HTML Template Post Email Dispatch in Django

In my Django project, I have set up functionality to send an email after a form submission using the smtplib module. The email is sent successfully, but for some reason, I'm encountering an issue where the corresponding HTML template (delivery_email_s ...

Hide elements forever once the form is submitted

I'm seeking help to figure out how to make certain elements disappear after a form submission on my website's dashboard page. Specifically, I need to hide three elements once the user has submitted a form. Elements that need to be hidden: .vc_t ...

Using React to Render a Component with Local Storage Information

I'm in the process of developing a history list component for a form within a react application and encountering difficulties with local storage. The goal is to display a list of previous user inputs from the local storage data. My current approach i ...

When trying to log the parsed JSON, it unexpectedly returns undefined even though it appears to be in good

Everything was working fine until a couple of days ago. Let's consider this as my PHP script: echo json_encode(array('stat'=>'ok')); I am sending an AJAX request to this script: $.post(base_url+'line/finalize/', {t ...

What could possibly be the reason for this not returning null?

Consider this JavaScript snippet: var value = parseInt(""); console.log(value != Number.NaN ? value : null); Why does the console output Nan instead of null? Is there a way to modify the code so that it actually returns a null value? I attempted to wra ...

Unexpected Disconnection of AJAX Response Moments Before Rebooting the Raspberry Pi

I currently have a LAMP server set up on my Raspberry Pi 4, where a web page is utilizing an AJAX call to trigger a php script that initiates a reboot of the pi. The php script echoes a JSON string response back to the web page indicating that it is prepar ...

Activate the function within the same class only for the selected item

Hello there, I'm struggling to grasp how to make this particular functionality work. Basically, I have 8 divs, each containing an image used as a button with the same class (tm-img), and hidden divs with additional information. My goal is to initiall ...

Invoke a function within a Vue 3 watch functionality defined within the setup method

Transitioning from Vue 2 to Vue 3 with Quasar has presented a challenge for me regarding watching a value that changes in a store file. In my layout page, I have a select dropdown that modifies the value of my background object in the store: stor ...

How can I specify to a Vue application that it will be situated in a subdirectory and have the image paths updated accordingly?

I have my Vue app located in a subfolder accessible via the URL: domain.com/myapp/ Within my component template, I currently use: <img :src= "base_path + '/img/undraw_profile.svg'"> where base_path is included in an imported fil ...

"Pairing Angular's loader with RxJS combineLatest for seamless data

Hey there! Currently, I'm working on enhancing my Angular application by implementing a global loader feature. This loader should be displayed whenever data is being fetched from my API. To achieve this, I am utilizing ngrx actions such as fetchDataAc ...

What is the process for rendering a Nested Component?

Let's develop a component that is used within another component on a webpage. Here's an example - MainComponent.tsx import NestedComponent from '../components/nestedComponent'; const MainComponent = () => { const { value, se ...

What is the best way to modify an array's property in order to achieve the desired outcome when using json_encode?

Expected Result ['#ff0000','#4caf50','#4caf50','#4caf50','#00bcd4','#00bcd4','#4caf50','#4caf50'] The output I am receiving is as follows: ["'#ff0000','#4caf5 ...

The Vue component is only receiving the initial parameter specified in the props

I am encountering a peculiar issue that I cannot seem to understand. Within my Laravel application, I am utilizing Vuejs 3. Specifically, I have developed a component named "MyComponent" which expects two numeric parameters via the use of props. Strangely, ...

Tallying the Number of Accordion Toggle Clicks

Let me present a scenario where I have some accordions and would like to keep track of how many times the user expands each one. Could you guide me on how to implement this particular feature? Appreciate your support, Kevin ...

Adding routing links to icons within carousels in Vuetify Nuxt.js: a step-by-step guide

Using js and Vuetify, I am trying to add Routing links to the icons in the Carousels. When I click on an icon, it should open a specific Routing link. However, my attempts have not been successful as the link is not working properly. Below is the code I tr ...

Could you please ensure that the animation activates upon hovering over the "a" element?

Utilizing bootstrap, I have created the following code. I am looking to add functionality that triggers an animation upon mouseover of an img or a element, and stops the animation upon mouseleave. .progress-bar { animation: pr 2s infinite; } @keyfr ...

I am looking to generate an array containing sub arrays so that I can easily iterate through the JSON data

I'm relatively new to creating subarrays and PHP, so please bear with me. I have some code that generates a JSON array, which is shown below. foreach ($result as $row) { $points = $row['points']; $price = ...

Failure to trigger custom event on FB pixel

I have installed the FB pixel helper browser plugin and I am confident that the FB pixel is properly implemented, as it is tracking pageviews correctly. However, I am facing an issue where the code for reporting a custom event is not working, even though ...

Tips on implementing VueStripe in a vue2 Project

I recently integrated Vue Stripe into my vue2 Project and encountered 2 similar errors in my code : Property 'redirectToCheckout' does not exist on type 'Vue | Element | (Vue | Element)[]'. Property 'publishableKey' does ...