Abdulsamet ILERI
Abdulsamet ILERI

Reputation: 165

How can I test actions within a Vuex module?

I want to test a vuex module called user.

Initially, I successfully registered my module to Vuex. Its works as expected.

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

import user from './modules/user'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    user
  }
})

export default store

My user module is defined as follows

store/modules/user.js

const state = {
  token: getToken() || '',
}

export const getters = {
  token: state => state.token,
}

const mutations = {
  [SET_TOKEN]: (state, token) => {
    state.token = token
  }
}

const actions = {
  [LOGIN] ({ commit }, body) {
    return new Promise((resolve, reject) => {
      login(body).then(response => { //login is an api method, I'm using axios to call it.
        const { token } = response.data
        setToken(token)
        commit(SET_TOKEN, token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  }
}

export default {
  state,
  getters,
  mutations,
  actions
}

login api

api/auth.js
import request from '@/utils/request'

export function login (data) {
  return request({
    url: '/auth/login',
    method: 'post',
    data
  })
}

axios request file

utils/request
import axios from 'axios'
import store from '@/store'
import { getToken } from '@/utils/auth'

const request = axios.create({
  baseURL: process.env.VUE_APP_BASE_API_URL,
  timeout: 5000
})

request.interceptors.request.use(
  config => {
    const token = getToken()
    if (token) {
      config.headers['Authentication'] = token
    }
    return config
  }
)

export default request

When I want to write some test (using Jest), for example login action as shown above.

// user.spec.js
import { createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'

import actions from '@/store/modules/user'

const localVue = createLocalVue()
localVue.use(Vuex)

test('huhu', () => {
  expect(true).toBe(true)
  // implementation..
})

How can I write test for my Login action? Thanks. Sorry for my beginner question.

EDIT: SOLVED Thank you Raynhour for showing to me right direction :)

import { LOGIN } from '@/store/action.types'
import { SET_TOKEN } from '@/store/mutation.types'
import { actions } from '@/store/modules/user'
import flushPromises from 'flush-promises'

jest.mock('@/router')
jest.mock('@/api/auth.js', () => {
  return {
    login: jest.fn().mockResolvedValue({ data: { token: 'token' } })
  }
})

describe('actions', () => {
  test('login olduktan sonra tokeni başarıyla attı mı?', async () => {
    const context = {
      commit: jest.fn()
    }
    const body = {
      login: 'login',
      password: 'password'
    }
    actions[LOGIN](context, body)
    await flushPromises()
    expect(context.commit).toHaveBeenCalledWith(SET_TOKEN, 'token')
  })
})

Upvotes: 1

Views: 4761

Answers (1)

Raynhour
Raynhour

Reputation: 136

Store it's just a javascript file that will export an object. Not need to use vue test util.

import actions from '../actions'
import flushPromises from 'flush-promises'
jest.mock('../api/auth.js', () => {
  return {
   login: jest.fn()..mockResolvedValue('token')
  }; // mocking API. 

describe('actions', () => {
  test('login should set token', async () => {
    const context = {
      commit: jest.fn()
    }
    const body = {
      login: 'login',
      password: 'password'
    }
    actions.login(context, body)
    await flushPromises() // Flush all pending resolved promise handlers
    expect(context.commit).toHaveBeenCalledWith('set_token', 'token')
  })
})

but you need to remember that in unit tests all asynchronous requests must be mocked(with jest.mock or something else)

Upvotes: 4

Related Questions