Guide to testing Vuex Mutations with Vue-test-utils and Jest

I have reviewed a few tutorials on mocking and testing Vuex actions, but I have struggled to implement them successfully on my own. Despite following the steps outlined in the links provided, I consistently encountered an issue where toHaveBeenCalled would return false. Is it not possible to mock Actions without replicating their actual functionality using jest.fn()? I'm confused as to why I am unable to achieve this.

store.js

export default new Vuex.Store({
  state: {
    currentSequence: ''
  },
  actions: {
    runGenerator({ commit, state }, currentSequence) {
      // do something with currentSequence
    }
  }
})

Home.vue (Note that this is not the complete code for this component, but includes important sections such as the submit.prevent method, the form html, and where the vuex action is called)

<template>
  <v-app id="inspire">
    <v-form @submit.prevent="setNextVal" id="sequence-form">
      <!-- form contents here -->
    </v-form>
  </v-app>
</template>

<script>
import { mapActions } from 'vuex'

export default {
  methods: {
    setNextVal() {
      this.runGenerator(this.form.currentSequence)
      this.form.currentValue = this.getCurrentValue
    },
    ...mapActions([
      'runGenerator'
    ]),
  }
}
</script>

store.spec.js

import { shallowMount, createLocalVue } from '@vue/test-utils'
import Vue from 'vue'
import Vuex from 'vuex'
import Vuetify from 'vuetify'
import Home from '@/views/Home.vue'

const localVue = createLocalVue()

localVue.use(Vuex)
Vue.use(Vuetify)

describe('Home.vue', () => {

  let actions
  let store

  beforeEach(() => {
    actions = {
      runGenerator: jest.fn()
    }
    store = new Vuex.Store({
      state: {
        currentSequence: ''
      },
      actions
    })
  })

  it('Dispatches "runGenerator" when submit.prevent has been triggered', () => {
    const wrapper = shallowMount(Home, { store, localVue })
    const form = wrapper.find('#sequence-form')
    form.trigger('submit.prevent')

    expect(actions.runGenerator).toHaveBeenCalled()
  })
})

Upon running the test, I received the following error:

expect(jest.fn()).toHaveBeenCalled() Expected mock function to have been called, but it was not called

What could be the missing piece? I would appreciate any insights or alternative solutions you might have. I have extensively reviewed online references, but haven't found any other solutions thus far.

Answer №1

While you may be making fun of the actions, they are still considered asynchronous in nature. When testing vuex, I always make sure to await async actions using flushPromises (which guarantees that any ongoing promises are resolved before moving forward with execution). To incorporate flushPromises into your project, follow these steps:

npm i -D flush-promises

After that, in your test script:

import flushPromises from 'flush-promises'

//...

it('Triggers "runGenerator" when submit.prevent is activated', async() => {
    const wrapper = shallowMount(Home, { store, localVue })
    const form = wrapper.find('#sequence-form')
    form.trigger('submit.prevent')

    await flushPromises();    

    expect(actions.runGenerator).toHaveBeenCalled()
})

Keep in mind that the test function has now been marked as async.

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

Creating a shared observable array in KnockoutJs to be used for multiple select elements

When an employer needs to assign a specific employee and premium amount, they can click on the "Add Employee" button to reveal another form with a dropdown menu of employees and an input field for the premium amount. <select> <option>John& ...

Retrieving & Refreshing Data with ajax and Jquery

I have been working on developing a forum system using jQuery, PHP, Bootstrap, and other technologies. The forum allows users to post, delete, and edit their posts. I have implemented an edit button for the author of the post, which triggers a modal wind ...

Troubleshooting Karate - jbang.execute() (Node npm)

Need help with a question that's part of our project presentation. We are working on controlling the output of KARATE, ensuring it returns an OK or a KO depending on the test result. Currently, it always gives back 0 regardless of success or failure. ...

What is the easiest way to choose a child vertex with just one click on mxgraph?

I have nested vertices and I'm looking to directly select the child vertex with just one click. Currently, when I click on a child vertex, it first selects the parent vertex instead. It's selecting the parent vertex initially: To select the ch ...

How can I connect the box using the Interactive Picture jQuery tool?

When using the Interactive picture jQuery, I have the following code snippet within my document: jQuery(document).ready(function(){ $( "#iPicture6" ).iPicture({ animation: true, animationBg: "bgblack", animationType: "ltr-slide ...

The content at “http://localhost:3000/script.js” could not be accessed because of a MIME type mismatch with the X-Content-Type-Options set to nosniff

I encountered an issue while attempting to transfer all the JavaScript to a separate js file and then adding that js file to the html per usual. The console displayed the following error message: The resource from “http://localhost:3000/public/main.js” ...

Make sure to close any existing Featherlight windows before trying to open another one

I'm setting up multiple featherlight instances when the page loads jQuery('.feedback').featherlight(jQuery( "#feedback-box" ), { closeIcon: 'close'}); jQuery('#imprint').featherlight(jQuery( "#imprint-box" ), { closeIcon ...

Tips on accessing close autoComplete/TextField title in AppBar

Looking to add a search bar and login button in the AppBar, where the search Bar is positioned close to the title. The desired order for the AppBar components should be as follows: Title SearchBox LoginButton How can this be achieved? Below is th ...

Insert text within the switch component using Material-UI

Looking to customize Material UI's Switch component with text inside? Check out the image below for an idea of what I'm going for. https://i.stack.imgur.com/KadRZ.png Take a look at my code snippet: import React from 'react'; import S ...

Is there a way for me to configure my website so that when a link is clicked, my PDF file will automatically open in Adobe

I've been facing an issue where I need my users to access a specific PDF file from a link on my website. Currently, the PDF opens in a separate tab next to my site, but ideally, I would like it to be forced to open in Adobe Reader directly. Is this ac ...

Clicking on the ng-repeat will trigger the ng-click event, which populates all the data using ng

I need help including an HTML page using ng-click within ng-repeat. However, it is currently loading all the content for every ng-repeat element. My specific requirement is to only bind(ng-include) the clicked element. Please see the attachment for m ...

Why does my VueJS method only execute after I save changes in VS Code instead of reloading the page? Can someone provide assistance?

Whenever I refresh the page, the console.log inside the method does not get executed until I make a change in VSC and save it. Is the show/hide modal for the form causing this issue? I tested removing the toggle but the problem persisted. Please refer to ...

Is there a way to compel Google Maps to load within my Angular application by implementing an Angular Directive?

I am encountering an issue where my Google Map fails to display most of the time. It seems that the map is not fully rendered when the rest of my data is populated in my Angular view. Is there a way to force the map to load? I have done some research and ...

What is the solution to the error message "A TypeError was encountered in the current module: e.parse is not a function"?

Can someone please help me resolve this Vue Js error I am encountering in Shopware 6 Administration? The issue pertains to selecting a column in the database table using a module. Note: Below is the complete code snippet. I am attempting to retrieve data ...

Does the onChange event fire when the value is modified by the parent element?

let [number, set_number] = useState({x: 1}); <ChildComponent number={number} onUpdate={onUpdateFunction} </ChildComponent> set_number({x: 2}) After running set_number({x: 2}), will this action prompt the execution of onUpdateFunction refere ...

The attempt to initiate the MongoDB server was unsuccessful. dbexit reported an error with code 48 within the MongoDB system

After updating MongoDB, I encountered an error. I attempted to restart the MongoDB service, but the error persists. ...

Do we need to use the "new" keyword when using ObjectID in a MongoDB query

Recently, I was immersed in a Typescript web project that involved the use of MongoDB and ExpressJS. One particular task required me to utilize a MongoDB query to locate and delete a document using the HTTP DELETE method. However, during the process of exe ...

ExpressJS does not support the 'Save' function

Working on a ticketing API using NodeJS + ExpressJS. Encountering an error when trying to modify a previously created ticket using the PUT method. Error /home/ismael/projects/nodejs-ticketing/routes/ticket.js:38 item.save(function(err){ ...

Error: Unable to convert Mongoose object to ObjectId

Currently tackling an issue with my small blog app and I seem to be stuck at this error- { "message": "Cast to ObjectId failed for value \" 597c4ce202ca9c353fc80e8a\" at path \"_id\" for model \"Blog\"", "name": "CastErr ...

Fade-in a new, revised text after fading-out the original text in ReactJS

I have a bunch of p elements that I'd like to cycle through, fading in one at a time and then replacing it with the next. Here is the jQuery example on CodePen: https://codepen.io/motion333/pen/EBBGVM Now, I'm attempting to achieve the same effe ...