Click trigger on button in vue-test-util is not activating

I am facing an issue with my Vue component that contains a button triggering a method on click. I am currently using Jest for unit testing. I expected the .trigger method from vue-test-utils to generate a synthetic event on the button, but it seems to be ineffective.

When I directly call the method on the wrapper with wrapper.vm.addService() and then check with console.log(wrapper.emitted()), I can confirm that an event is indeed being triggered. So, my confusion lies in why addServiceBtn.trigger('click') is not yielding any result.

The output of console.log(wrapper.emitted()) shows an empty object and the test fails with the error message:

Expected spy to have been called, but it was not called.

ServiceItem.vue

<template>
  <v-flex xs2>
    <v-card>
      <v-card-text id="itemTitle">{{ item.title }}</v-card-text>
      <v-card-actions>
        <v-btn flat color="green" id="addServiceBtn" @click="this.addService">Add</v-btn>
      </v-card-actions>
    </v-card>
  </v-flex>
</template>

<script>
export default {
  data: () => ({
    title: ''
  }),
  props: {
    item: Object
  },
  methods: {
    addService: function (event) {
      console.log('service item')
      this.$emit('add-service')
    }
  }
}
</script>

tests.spec.js

import { shallowMount, mount } from '@vue/test-utils'
import ServiceItem from '@/components/ServiceItem.vue'
import Vue from 'vue';
import Vuetify from 'vuetify';

Vue.use(Vuetify);

describe('ServiceItem.vue', () => {
  it('emits add-service when Add button is clicked', () => {
    const item = {
      title: 'Service'
    }

    const wrapper = mount(ServiceItem, {
      propsData: { item }
    })

    expect(wrapper.find('#addServiceBtn').exists()).toBe(true)
    const addServiceBtn = wrapper.find('#addServiceBtn')

    const spy = spyOn(wrapper.vm, 'addService')

    console.log(wrapper.emitted())
    addServiceBtn.trigger('click')
    expect(wrapper.vm.addService).toBeCalled()

  })
})

Answer №1

There appears to be a small error in your HTML code. You have bound the @click event to your method without including this. It should be coded as follows:

 <v-btn flat color="green" id="addServiceBtn" @click="addService($event)">Add</v-btn>

Answer №2

One reason why the tests in the original code were not working is due to the use of parenthesis in the function call. It has been discovered that using the syntax @click="addService" will cause the tests to fail, whereas a similar, albeit discouraged, syntax like @click="addService()" will pass.

For example:

test('Click calls the right function', () => {
    // wrapper is declared before this test and initialized inside the beforeEach
    wrapper.vm.testFunction = jest.fn();
    const $btnDiscard = wrapper.find('.btn-discard');
    $btnDiscard.trigger('click');
    expect(wrapper.vm.testFunction).toHaveBeenCalled();
});

This test was failing with:

<button class="btn blue-empty-btn btn-discard" @click="testFunction">
  {{ sysDizVal('remove') }}
</button>

but passed with:

<button class="btn blue-empty-btn btn-discard" @click="testFunction()">
  {{ sysDizVal('remove') }}
</button>

Answer №3

For me, the event didn't trigger properly when testing with vue-test-utils until I included .native

<v-btn @click.native="addToCart($event)">
      Add
</v-btn>

Answer №4

The issue occurred because when using this.addService in the <template>, it is advised to remove the this and simply use either @click="addService($event)" or @click="addService". Both methods will work effectively, but the latter does not pass any event.

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 could be causing the Twitter Timeline to fail to load based on a variable in a Vue.js component?

My goal is to display the Twitter timeline of multiple accounts based on the route. I initially attempted to use a plugin called vue-tweet-embed, but encountered issues with it. As a result, I resorted to the traditional method by embedding twitter's ...

Utilize the arrow keys to navigate through the search suggestions

I am facing an issue with my search bar where I am unable to navigate through the suggestions using arrow keys. I have been struggling with this problem for days and would appreciate any help in resolving it. var searchIndex = ["404 Error", "Address Bar ...

Capturing an image of an HTML5 canvas that includes an image object: tips and tricks

After creating a canvas and adding various objects like images, clipart, and text to it, I encountered an issue. When capturing a snapshot of the canvas with only text using the method `canvas.toDataURL()`, the snap is correct. However, when I include an i ...

What is the best way to verify a user's login status in AngularJS using $routeChangeStart event?

I am new to AngularJS and I need help checking if my user is logged in or not using $routeChangeStart. Controller angular.module('crud') .controller('SigninCtrl', function ($scope,$location,User,$http) { $scope.si ...

Using Vue 3, Bootstrap, and Pinia to create an innovative Global Modal experience

After creating a ModalComponent.vue file that I intend to use across different sections, I encountered an issue with closing the modal after calling my Pinia stores. The modal includes slots for the title, body, and footer, along with a standard close butt ...

Step-by-step guide for importing a JSON file in React typescript using Template literal

I am facing an error while using a Template literal in React TypeScript to import a JSON file. export interface IData { BASE_PRICE: number; TIER: string; LIST_PRICE_MIN: number; LIST_PRICE_MAX: number; DISCOUNT_PART_NUM: Discout; } type Discoun ...

Obtaining the Final Document Identifier for Paginating with valueChanges()

When using valueChanges() in AngularFire to subscribe to Firestore data, I encountered an issue where obtaining the last document reference for pagination was not as straightforward as when using onSnapshot. Unfortunately, the approach I was using with o ...

The NGX countdown timer is experiencing a discrepancy when the 'leftTime' parameter exceeds 24 hours, causing it to not count down accurately

When the leftTime configuration exceeds 864000, the timer does not start from a value greater than 24 hours. <countdown [config]="{leftTime: `864000`}"></countdown> For example: 1. When leftTime is set to `864000`, the Timer counts down from ...

Issue with Plesk Obsidian, IISNode, and Express - application functioning solely in local environment

After setting up my Node.JS + Express.JS application on my server with IISNode and Plesk Obsidian, browsing the page in a browser triggers an error: I have already verified the permissions of the relevant folders and ensured that the "App Identities" have ...

Vue-Router: Altering the view of a parent component with a child route

In my parent view, I have a list and some metadata displayed in a right pane. I'm looking to replace the right pane component with specific item data when clicked on the list: export default { mode: 'history' base: process.env.BASE_URL, ...

Guidelines for securing login access where the "IsApproved" field must be true before authorization

During the account registration process, I initially set the default value to false for the field IsApproved. I need to create security rules that allow login only for users with IsApproved:true, and redirect those with IsApproved:false to the accessdenied ...

Performing an Ajax post request to a PHP script in order to retrieve a PHP variable using XMLHttpRequest

I am looking to dynamically update my table using JavaScript every few seconds. Currently, I have set up an AJAX post request to my update.php file and trigger it if it is set. Then, I execute a MySQL query to retrieve the data and store the resultset in ...

Crushing jQuery's Sortable/Droppable

Having a little issue here. I want to be able to toggle the sortable plugin's behavior by clicking a button - basically switching between sort mode and view mode. I've attempted to achieve this with the following code: function enterSortMode(){ ...

The use of Angular's ng-pattern leads to disruption in the binding process

Here is the form I am working with: <div class="panel-group"> <label for="url" tooltip="Enter the Engine as a Web Service (EWS) URL the Empower Editor will use for PDF preview.">EWS URL</label> <input id="url" size="50" ng-mod ...

Combining Laravel and VueJs for a Multi-Page Application (MPA)

I have recently developed a website using a combination of Laravel and VueJs. However, I am facing some confusion regarding the most suitable routing architecture to implement. Currently, my application has the following setup: The routing system is man ...

What is the best way to retrieve AJAX responses from JSON data that contains multiple sets of information

["12-Feb-2017","06-Feb-2017","5","45","40","Neha shishodia","USD","unit2","phase1","Change Request","Client Approval Awaited"]["07-Feb-2017","04-Feb-2017","6","54","48","Neha shishodia","USD","unit2","phase1","Change Request","Manager Approval Awaited"] T ...

Issue with React-Axios: File data being sent to Node server is undefined

My current challenge involves uploading a single file and saving it in a specific folder within my app directory. While I can successfully choose a file on the frontend and update the state of the Uploader component, I encounter an issue when sending a POS ...

How do I store the result of an Ajax request as a variable in a different function within a React component?

One of the challenges I'm facing involves making an ajax call that retrieves a list of movies, and then running another function with a separate ajax call to fetch the genre names. Since the first call only provides the genre IDs, I need to match each ...

Having trouble in React.js when trying to run `npm start` with an

Upon initially building a todo app in react.js by using the command: npx create-react-app app_name When I proceeded to run the command npm start, it resulted in displaying errors: https://i.sstatic.net/BxYFu.png https://i.sstatic.net/EqU1j.png In furth ...

Using Vue.js to toggle rendering based on checkbox selection

Struggling to conditionally render form elements in Vue based on user input. I can do this with VanillaJS or jQuery, but struggling to implement it with Vue's built-in conditional directives. Using single-file components with the webpack template from ...