How Vue and Jest work together: parent component handles custom event triggered by child component

I am currently facing a challenge with testing a set of parent and child Vue components. The child component emits an event that is handled by the parent component. I want to verify that the custom event is handled correctly, but I've hit a roadblock.

Below is the code snippet for the Parent.vue file:

<template>
  <div id="app" class="container">
    <!-- phonebook -->
    <ChildComponent
      class="row mt-4"
      @customEvent="val => customEventHandler(val)"
    ></ChildComponent>
  </div>
</template>

<script>
  import ChildComponent from './components/ChildComponent.vue'

  export default {
    name: 'App',
    components: {
      ChildComponent,
    },
    data() {
      return {
        test: [1, 2, 3, 4]
      };
    },
    methods: {
      customEventHandler(id) {
        // removes item `id` from the `test` array
        this.test = this.test.filter((item) => item !== id);
      },
    }
  };
</script>

I have attempted to write tests for this scenario in the Parent.spec.js file, but unfortunately, they are failing. Here is one of the tests:

import { mount, shallowMount } from "@vue/test-utils";
import  Parent from '../../src/Parent.vue';
import  ChildComponent from '../../src/components/ChildComponent.vue';

describe('Testing the customEvent event', () => {
  beforeEach(() => {
    parent = mount(Parent, {
      data() {
        return {
          test: [1, 2, 3, 4]
        };
      },
    });
  });

  it('should trigger the customEventHandler method', async() => {
    const spy = jest.spyOn(parent.vm, 'customEventHandler');
    await parent.findComponent(ChildComponent).trigger('customEvent', 2);

    expect(spy).toHaveBeenCalled();
  })
})

Even though I have also tried other variations of tests, such as verifying the arguments passed to the spy or checking for side effects caused by the customEventHandler method, all of them seem to fail. It feels like the event isn't being triggered at all, or perhaps I'm attempting something that's not feasible.

Is there a recommended approach to properly test a parent component's handling of events emitted by its child component?

Answer №1

Interacting with Events

trigger() is designed for triggering native DOM events. When dealing with custom events, you can utilize wrapper.vm.$emit() (and there's no need to await it):

// await parent.findComponent(ChildComponent).trigger('customEvent', 2);
//                                            ^^^^^^^ ❌

parent.findComponent(ChildComponent).vm.$emit('customEvent', 2);

Monitoring Methods

In Vue 2, spying on methods through the wrapper.vm instance is not supported. Instead, you should spy on the component definition (Parent.methods) prior to mounting:

// const spy = jest.spyOn(parent.vm, 'customEventHandler');
//                        ^^^^^^^^^ ❌ not supported in Vue 2

const spy = jest.spyOn(Parent.methods, 'customEventHandler')
const parent = mount(Parent)

demo

It's worth noting that Vue 3 does offer support for method spying via wrapper.vm.

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

Contrasting the lib and es directories

I am seeking clarity on my understanding. I am currently working with a npm package called reactstrap, which is located in the node_modules folder. Within this package, there are 4 folders: dist es lib src I understand that the src folder contains the s ...

What could be causing my Node.js website to have trouble locating pages in the public directory?

Embarking on my journey in web development using node.js, I encountered an issue while trying to load a particular page, which led to the following error message in my browser: Cannot GET /public/pages/terms-and-conditions.html The file structure is orga ...

What is the best way to delete a nested document within an array in MongoDB by referencing its _id?

I am trying to remove a nested object from an array of objects called createdEvents if the createdEventId matches the id I pass to it. This is the JavaScript query I am using: db.collection("users").updateOne({ _id: userId }, { $pull: { createdEv ...

Tips on harnessing the power of AngularJS $scope

In need of assistance! I have a paragraph and a counter that I want to update whenever the user clicks on the paragraph, all using AngularJS. Below is the code snippet I've come up with: <!DOCTYPE html> <html> <head> <script src= ...

Creating websites with Single-page applications by assembling HTML and JS fragments at build-time

As I prepare to tackle a large single-page app project, my main focus is on finding a more efficient way to develop it other than cramming everything into one massive file. My priority is ensuring the maintainability and testability of the app, which is wh ...

Tracking progress within an HTML table

I am facing an issue with a table that is designed to display progress bars for each method or task stored in the database. These progress bars are determined by two dates: the startDate and endDate. However, I have noticed that the progress bar only funct ...

Is there a CSS rule that can alter the appearance of links once they have been clicked on a different webpage?

Just starting out here. Imagine I have 4 distinct links leading to the same webpage - is there a way to modify the properties of the destination page depending on which link was clicked? For instance, clicking on link1 changes the background color of the d ...

Implementing a 10-second alert display in selenium

Task at Hand: I need to display the alert on my page for a few seconds to allow reading. Is there any function in Selenium Web-driver that can help with this? I am new to automation and have been learning about explicit waits. I tried using explicit wait ...

What is preventing me from retrieving the data stored in my JSON?

My PHP code snippet involves checking if POST data is not empty and the action is 'edit'. If this condition is met, it fetches data from the database based on the selected IDs and prepares a JSON response. if(!empty($_POST)&&($_POST[&apo ...

Divide HTML elements every two words

Can you use CSS to break up HTML content after every 2 words, ensuring it works for any word combination? Example: // Original HTML content The cat is sleeping // Desired result: The cat is sleeping ...

Nested tables in Datatables retrieving child table rows based on parent table

I have been struggling for the past three days to get my nested Datatables working properly. I have a parent table called MAINtable and a child table called adjlinesTable. The issue I am facing is that all lines from the adjlinesTable are being drawn to ...

Having trouble incorporating this JavaScript code into customizing my material design chips

Having trouble integrating this code snippet into a React.js project. When I try to add it as a function, I get an error message saying that $ is not defined. I've experimented with different methods, but so far, I haven't been successful in gett ...

The task "default" is not found within your current gulpfile configuration

After running gulp in my console, I encountered the following error: Task 'default' is not in your gulpfile I double-checked my gulpfile and it appears to be correct: var gulp = require('gulp'), LiveServer = require('gulp- ...

AngularJS - Best practices for defining Angular modules

Imagine you have an angular js app called myApp with a controller and directive. How should you go about declaring both components? angular.module("myApp",[]) .controller("myController"...... angular.module("myApp") .directive("myDirective"....... OR a ...

Oops! Gulp encountered an error: Assertion Error [ERR_ASSERTION]: You must specify a task function

Being new to javascript, I attempted to execute some repositories from GitHub. After installing all the required updates and running npm audit --force, I am still encountering this error. Any assistance would be greatly appreciated. Error Code : PS D:&bso ...

List item with React Material UI tooltip

click here for image preview Exploring the idea of incorporating a customized tooltip component using React Material UI. The goal is to leverage the tooltip, list item, and list components provided by React Material UI. I have experimented with utilizing ...

Invoking the .html(result) function multiple times within the AJAX success callback

I have implemented this code in my template to handle my ajax request: <script> $(document).ready(function() { $("#send-mail-button").click(function(e){ e.preventDefault(); var nameVar = $('#name&apo ...

Arranging date and time in jQuery based on AM/PM notation

I have written some JavaScript code to sort dates in ascending order (from newest to oldest). I have successfully sorted the dates, but I am having trouble sorting the time with AM or PM using a 12-hour format. I can do it in a 24-hour format, but not in ...

Replace the identifier with the corresponding ID if it aligns with another ID when using Node.js or JavaScript

const info = [ { system: { id: "4gSSbjCFEorYXqrgDIP2FA", type: "Entry", content: { type: { name: "Writer" } }, }, InfoDetails: { shortSlugOption: { "en-us": "some value", "za-op": "random value" }, mediaFileAsset ...

Obtaining a variety of data points from an XMLHttpRequest

I recently discovered a technique for sending multiple variables on SO. Here is the code snippet I used: xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET","http://127.0.0.1:3000?var1=" + name + "&var2=test", true); xmlhttp.send(); xmlhttp.onreadystat ...