Exploring the Power of Jest and Vue Test Utils for Unit Testing in VueJS

Having recently started Unit Testing with vue, I am currently working on unit testing a navigation vue component. My initial goal was to test a method that simply sets a boolean value to false upon clicking. Utilizing vuetify, I attempted to replicate a button and hoped that the variable (showLoginDrawer) I pass would return false in my unit test. However, I encountered an error: TypeError: _vm.is.has is not a function, which seems to be related to a different part of my code. Despite searching online, I couldn't find a solution.

Below are the component and testing file snippets:

//Nav.vue
<template>
  <v-btn
        :to="{ name: 'home' }"
        aria-label="Home button"
        @click="hideDiv()"
   >
   </v-btn>

      <div>
        <transition name="nav-fade">
          <component v-bind:is="drawerSection"></component>
        </transition>
      </div>

</template>
...
//Nav.spec.js
import Vue from 'vue'
import Vuex from 'vuex'
import Vuetify from 'vuetify'
import { shallowMount, mount } from '@vue/test-utils'
import Nav from '@/components/Nav'

...

describe('Testing Nav component', () => {
    ...

    test('Test Button click when logged out', () => {
    const wrapper = mount(Navigation, {
      data() {
        return {
          appState: {
            showLoginDrawer: true,
            lastCapabilityPath: '',
            restrictedAccessAlert: false,
          },
          is: 'learning',
          localVue,
          vuetify,
        }
      },
    })

    ...
  })
})

Upon running the test, I encounter the following error:

TypeError: _vm.is.has is not a function

Any assistance would be greatly appreciated!

Answer №1

My error was assuming that has() could work with a string, when in fact it is a set function and requires the variable to be set as a set in order to function properly.

Revised code snippet:

  test('Test Basic HTML rendering', () => {
    const checkSet = new Set(['learning', 'b', 'c'])

    const wrapper = mount(Navigation, {
      data() {
        return {
          appState: {
            showLoginDrawer: true,
            lastCapabilityPath: '',
            restrictedAccessAlert: false,
          },
          checkSet,
          localVue,
          vuetify,
        }
      },
    })
    wrapper.vm.$vuetify.breakpoint.smAndUp = true
    expect(wrapper.html()).toContain('Log-in')
    // verifying component name
    expect(wrapper.vm.$options.name).toMatch('NavProfile')
  })

Answer №2

It is recommended to implement the usage of async & await as each event call may be asynchronous.

describe('Testing Nav component', () => {
    let vuetify
    beforeEach(() => {
        vuetify = new Vuetify()
    })

    test('Test Button click when logged out', async () => { // utilize async
        const wrapper = mount(Navigation, {
            data() {
                return {
                    appState: {
                        showLoginDrawer: true,
                        lastCapabilityPath: '',
                        restrictedAccessAlert: false,
                    },
                    is: 'learning',
                    localVue,
                    vuetify,
                }
            },
        })

        const event = jest.fn()
        const button = wrapper.findAll('.v-btn').at(0)
        expect(button.text()).toContain('My Profile')

        button.vm.$on('click', event)
        expect(event).toHaveBeenCalledTimes(0)
        expect(wrapper.vm.showLoginDrawer).toBeTruthy()

        // Use await for each event
        await button.trigger('click')
        expect(event).toHaveBeenCalledTimes(1)
        expect(wrapper.vm.showLoginDrawer).toBeFalsy()
    })
})

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

Utilizing AngularJS to access the corresponding controller from a directive

When I have HTML structured like this... <div ng-app="myApp"> <div ng-controller="inControl"> I enjoy sipping on {{beverage}}<br> <input my-dir ng-model="beverage"></input> </div> </div> a ...

How can I create a JSON string that exactly matches the data source needed for a pie chart? Any tips

received JSON string: "{Date:'15/05/2015',y:'6'}, {Date:'01/08/2015',y:'6'}, {Date:'02/08/2015',y:'6'}, {Date:'08/08/2015',y:'72'}, {Date:'09/08/2015',y:&apo ...

Angular2 Error: Issue with the "match" function in JavaScript

Why am I receiving a typeerror that says "cannot read property of 'match' undefined"? var numInput = document.getElementById('input'); // Listen for input event on numInput. numInput.addEventListener('input', function(){ ...

Despite calling this.setState to update my state, the render() method is still displaying the previous values

class EditLocation extends Component { constructor(props) { super(); this.state = { LocationId: '', locationOptions: [], } this.baseState = this.state; this.findLocationById = this ...

Starting an AngularJS module without an HTML page may seem like a daunting task,

I am currently developing a browser extension project using AngularJS. Within the background.js file (which contains the code that runs in the background), I have created a module with a run block. var myExtensionModule = angular.module('myExtension ...

Export was not discovered, yet the names are still effective

There seems to be a slight issue that I can't quite figure out at the moment... In my Vue project, I have a file that exports keycodes in two different formats: one for constants (allCodes) and another for Vue (keyCodes): export default { allCodes ...

Guide to creating a production build for electron with react js and next framework

Currently, I am working with electron using react js and next. I am struggling to figure out how to create its production build. Can someone provide me with assistance along with a detailed step-by-step guide? app node_modules pages routes static packa ...

Creating a Cancel Button in JSP/HTML/JS/CSS Form: A Step-by-Step Guide

It is necessary to incorporate the functionality of "save" and "cancel" in the JSP code for this particular form. By selecting "save", the data entered into the form will be submitted to its intended destination. Alternatively, choosing "cancel" will dismi ...

Calculating the difference between the old scrolltop and the new scrolltop in jQuery/Javascript

I have a seemingly straightforward question, yet I am struggling to find a solution. Each time a user scrolls, the scrollTop value changes. I want to subtract the previous value from the new value of the scrollTop. However, I am unsure how to store the old ...

Is there a way to locate a parent class starting from a child class, and subsequently track down another child class from the parent?

I am facing a challenge with multiple tags structured like this: <div class="A"> <div class="B1">...</div> <div class="C1">Hello World!</div> <div class="C2">World Hell ...

Watching a service's attribute from within a route in the EmberJS framework

There seems to be a concept that I'm struggling to grasp here. To my understanding, any instance of Ember.object should be able to observe properties on another instance of Ember.object. In my scenario, there is a service, a router, and a component i ...

Leveraging the Spread Operator in Redux mapDispatchToProps with SweetAlert2

When I add the swal action creators to the mapDispatchToProps function like this: function mapDispatchToProps(dispatch) { return { getAnimal: (_id) => dispatch(getAnimal(_id)), ...swal } } The issue aris ...

Gain a comprehensive understanding of the JavaScript syntax utilized throughout the code

I stumbled upon this JavaScript code that enables asynchronous file uploads, but there are certain parts of it that I'm struggling to grasp. Any insights or explanations would be greatly appreciated - many thanks in advance. // Utilizing Ajax for Fil ...

Comparing a series of smaller strings to a larger string for testing purposes

My website has an array filled with bot names. Whenever a user or bot visits the site, I retrieve the user-agent and want to check if any of the values in my array are present in it. var bots = [ "twitterbot", "linkedinbot", "facebookexternalhit", ...

Exploring multilingual options with VeeValidate/i18n in version 4

Previously, I utilized VeeValidate v2 and had a setup like this: VeeValidate.Validator.localize('en', customErrors); const customErrors = { custom: { someField: { required: 'error.required', }, ... }} I have JSON files such ...

Axios fails to dynamically update Apexchart

I'm having trouble with the updateSeries function in my code. Even though the uChart() function is being called, I can't seem to figure out why it's not working. Here is the code snippet: <template> <div> <Menu></Me ...

Continue running web AJAX request in Android browser while it is minimized

I need help with my AJAX call var tid = setInterval(mycode, 2000); function mycode() { $.ajax({ url:'/ajx.php', type: "GET", success: function (data) { }, ...

loading the css and javascript files based on the specified prop parameter

In the process of working on a ReactJS file that utilizes the react-ace library, I currently have the following code implemented. import React, { Component } from 'react'; import 'brace/mode/html'; import 'brace/theme/monokai&apos ...

How can we pass the onClick prop from a child component to a parent component in React with Typescript?

Currently, I am utilizing React along with TypeScript. I am curious about the process of passing an event from the parent component to a child component using props. Here is an example for better understanding: parent.tsx const ParentComponent: React.F ...

What are the best ways to transfer information between functional components in a React application?

When working with React, data exchange between class-based components can be done using states and props in the following way: App.js import Name from './Name'; import React, { Component } from 'react' export class App extends Compo ...