Trying out a Vuex action that communicates with an external API

I'm working on a Vue.js project where I have the following Vuex action:

import { HTTP } from '@/services/http'

export const actions = {
  loginUser ({ commit }, params) {
    HTTP.post(
      'v1/login',
      { email: params.email, password: params.password }
    ).then(response => {
      localStorage.setItem('access_token', response.data.token)
      commit('SET_USER', response.data)
    }).catch(error => {
      commit('SET_LOGIN_ERROR', error.response.data.error)
    })
  }
}

Currently, I am using Mocha + Karma for my unit tests. Could someone please advise me on how to properly test this action?

Answer №1

Ensuring that dependencies are properly mocked/stubbed is crucial. One of the first challenges you might encounter is mocking the HTTP service, as your tests may fail without an active Internet connection to the backend server. Consider exploring dependency injection as a solution.

When testing actions, I found inspiration in Vuex's recommendations. It involves creating a stub for the commit function that can verify the type and payload of each mutation called by the action, comparing it with the expected outcomes. If the list of mutations triggered by the commit stub matches those anticipated when the action executes, then the test is successful.

While this example is simplistic and not intended for production use, it serves as a demonstration:

let count = 0
let errors = []
let mutations = [
  { type: 'SET_USER', payload: 'expected response.data value' }
]

function commit(type, payload) {
  const mutation = mutations[count]

  try {
    expect(mutation.type).to.equal(type)
    if (payload) { expect(mutation.payload).to.deep.equal(payload) }
  } catch (error) {
    errors.push(error)
  }

  count++
}

actions.loginUser({ commit }, { email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5a3c3b313f1a3f373b333674393537">[email protected]</a>', password: '12345' })

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

The environmental variables stored in the .env file are showing up as undefined in Next.js 13

I am having trouble accessing the environment variables stored in my .env.local file within the utils folder located in the root directory. When I try to console log them, they show as undefined. console.log({ clientId: process.env.GOOGLE_ID, clien ...

Incorporate attributes into object properties in a dynamic manner

Currently, I am experimenting with bootstrap-multiselect and my goal is to incorporate data attributes into the dataprovider method. Existing Data Structure: var options = [ {label: 'Option 1', title: 'Option 1', value: ' ...

Creating responsive D3.js charts for various screen sizes and devices

After creating a chart using d3.js, I noticed that the chart does not resize when zooming in or out on the web browser window. Below is the code snippet of what I have attempted so far: <!DOCTYPE html> <html> < ...

js/jquery issue with IE: Scrolling to the bottom of a div upon page load

I have encountered an issue with my code on Internet Explorer. It works perfectly on Firefox, but when the content of the div is too high in IE, it fails to scroll to the bottom. Clicking a button to scroll to the bottom works fine, but the problem arise ...

Event emitting from a parent Vue.js component

I can't figure out why my code is not functioning properly. I have an event called 'leave' that should be triggered on blur. The components show up correctly, but the event doesn't fire when leaving the inputs. Vue.component('te ...

Notify when the SVG object is clicked based on its identifier

I'm interested in adding more complexity to this project, but before I can proceed, I need to be able to detect when a specific object element containing an SVG image with an ID is clicked. Each object is nested within a div. <div class="grid 18"&g ...

Issues with Autofocus in AngularJs on Firefox

Check out this straightforward directive to set autofocus: app.directive('autoFocus', function($timeout) { return { restrict: 'AC', link: function(_scope, _element) { $timeout(function(){ ...

Strategies for Iterating Through Array Elements Multiple Times

When I want to log the numbers one to five just once, I usually use code like this: var array = [1,2,3,4,5] function loop(n) { for (var i=0;i<n;i++) { console.log(array[i]) } } loop(5) However, if I want to log the numbers one to five multip ...

Developing a personalized loop in handlebars templates

Just starting out with NodeJS and ExpressJS. I'm looking to customize a for loop in order to iterate through data from NodeJS using an index, akin to a non-traditional for loop. Take a look at the code snippet below, extracted from NodeJS, where I re ...

Is it necessary to ensure application readiness before proceeding with unit testing exports?

I've been facing a challenge while trying to utilize Jest for unit testing an express API that I've developed. The issue arises when the database needs to be ready before running the test, which doesn't seem to happen seamlessly. In my serve ...

Create a personalized Command Line Interface for the installation of npm dependencies

I am looking to develop a Node CLI tool that can generate new projects utilizing Node, Typescript, Jest, Express, and TSLint. The goal is for this CLI to create a project folder, install dependencies, and execute the necessary commands such as npm i, tsc - ...

Retrieving data from a JSON file at 10-minute intervals with Ajax and visualizing it on Google's globe API

After downloading Armsglobe, a globe API provided by Google to draw lines in countries using their names, I noticed that the original code does not fetch JSON data periodically. I attempted to use a simple setTimeout() function in dataloading.js to address ...

The button remains stationary when it is clicked

After creating a button that should move to a random position upon being clicked, I encountered an issue with the document.style.top property not functioning as expected. I have already created two variables for height and width to generate random values, ...

Resolve the issue with automatically generating SCSS type definitions (style.d.ts) for Preact within a TypeScript webpack setup

Utilizing webpack with Preact 10.x (nearly identical to React) and TypeScript in the VSCode environment. Following an update from Node version 12 to version 14, there seems to be a problem where *.scss files no longer automatically generate their correspo ...

Dropdown menu for selecting state in multiple countries built with React JS

In my project, I'm attempting to create a dropdown menu that lists multiple countries along with their associated states by mapping over an array. The sample data from the array is shown below: [ { "country" : "USA", ...

What causes ngDoCheck to be triggered upon setTimeout resolution?

I'm pondering why ngDoCheck gets triggered when setTimeout finishes. Here is a simple component setup I have: @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css ...

Retrieve the specific key or object number by conducting a search in JavaScript

I am faced with the challenge of editing a large XML file by searching for a specific keyword within the "event name" field and changing the corresponding "active" value to either 1 or 0. The structure of the data file is as follows. I have managed to modi ...

Discover the following `<td>` identifier through the act of clicking on a separate `<td>` element

I have a few td's with specific ids: <td id="first">first</td> <td id="second">second</td> <td id="third">third</td> <td id="fourth">fourth</td> Whenever I click on one of the td elements, I want to re ...

What is causing the inefficacy of this particular SQL request method, while the alternative one proves effective?

It's surprising that the one not working is from the mssql package page. Why isn't it functioning on my machine? What am I missing here? The other example I found online works perfectly. On a side note - should these requests be done asynchronou ...

What is the best way to bind a model to a directive in Angular.js?

I have been experimenting with different methods to create a two-way binding between my directive and repeater, but so far I haven't been successful. Although I have tried various strategies suggested online, the current setup does not pass item.myDat ...