DEV Community

Paulo
Paulo

Posted on

How to test Vuex with Nuxt

Hello, in this article we will learn how to test Vuex. We are going to use the Nuxt.js framework to create the project, first what is Vuex, Vuex is a state management standard for Vue.js applications. It serves as a centralized store for all components in an application, with rules ensuring that state can only be mutated in a predictable way. Our project will be a simple project, it will be an application to increment and decrement a number, let's start.

Install Vue:

npm install -g @vue/cli
# OR
yarn global add @vue/cli
Enter fullscreen mode Exit fullscreen mode

You can check you have the right version with this command:

vue --version
Enter fullscreen mode Exit fullscreen mode

When creating the project you will have some project configuration options you can feel free to choose your configuration, but you must select Jest in Testing framework, I will show you the options chosen when creating this project:

Programing language: Javascript
Package manager: npm 
UI framework: none
Nuxt.js modules: axios
Linting tools: Eslint, Prettier e Lint staged files
Testing framework: Jest
Rendering mode: Universal
Deployment target: Serve
Deployment tools: jsconfig
Continuous integration: None
Version control system: Git
Enter fullscreen mode Exit fullscreen mode

command to create project:

npm init nuxt-app <project-name>
# OR
npx create-nuxt-app <project-name>
Enter fullscreen mode Exit fullscreen mode

Okay, after creating the project we are going to install a dependency that will help us in the development of the tests

npm install @types/jest --save-dev
Enter fullscreen mode Exit fullscreen mode

After all the installations we go to the package.json file to add one more script.

"test:watch": "jest --watchAll",
"test:coverage": "jest --coverage",
Enter fullscreen mode Exit fullscreen mode

before running the script, go to the jest.config.js file to make some changes, add the false value to collectCoverage, as this will not generate coverage for each change made to the project and the next change is to add to collectCoverageFrom the store directory that is /store/*/.js this will make jest run in the store folder.

Now we can run this command:

npm run test:watch
Enter fullscreen mode Exit fullscreen mode

Ready now the project is running the tests, when finishing these settings let's go to practice let's create a file in the store folder with the following name counter in nuxt.js already perform the export of the file with the name you put in the file the nuxt .js already does this automatically. In our article we just need the state which is an object that contains all the state of your application and serves as the "single source of truth" and mutations which is the only way to actually change state in a Vuex store.

As we are developing using the TDD method (Test Driven Development) in which we write the test first that the functionality is now going to create another file that will be the test file the file name will be counter.unit.spec.js it can be created in the same folder where the counter is or in a test folder.

We are going to carry out the necessary imports to carry out the tests, we must import createLocalVue, vuex and its store. Stays like this:

import { createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'
import { mutations, state } from '@/store/counter.js'
Enter fullscreen mode Exit fullscreen mode

now let's create the tests first let's group the tests inside a describe and describe also describes what those tests are. Inside the describe we will create a function that will be called and return the store and with this store we will be able to access the state, mutations, actions and getters. the describe with the function is like this:

describe('Counter store', () => {
  const createStore = () => {
    const localVue = createLocalVue()
    localVue.use(Vuex)

    const store = new Vuex.Store({ state, mutations })

    return { store }
  }
})
Enter fullscreen mode Exit fullscreen mode

The first test we are going to create will be the test to see the state of the value of the counter where its initial value is zero. The first test looks like this:

describe('Counter store', () => {
  const createStore = () => {
    const localVue = createLocalVue()
    localVue.use(Vuex)

    const store = new Vuex.Store({ state, mutations })

    return { store }
  }

  it('State => counter should start with the value zero', () => {
    const { store } = createStore()
    expect(store.state.counter).toEqual(0)
  })
})
Enter fullscreen mode Exit fullscreen mode

now let's test the mutations when the increment method is called the value of the counter must increase one more example the value of the counter is 0 when the increment is called the value of the counter must be 1. The code looks like this:

describe('Counter store', () => {
  const createStore = () => {
    const localVue = createLocalVue()
    localVue.use(Vuex)

    const store = new Vuex.Store({ state, mutations })

    return { store }
  }

  it('State => counter should start with the value zero', () => {
    const { store } = createStore()
    expect(store.state.counter).toEqual(0)
  });
  it('Mutation => should increment one more when increment is called ', () => {
    const { store } = createStore()
    store.commit('increment')
    expect(store.state.counter).toEqual(1)
    store.commit('increment')
    expect(store.state.counter).toEqual(2)
  })

})
Enter fullscreen mode Exit fullscreen mode

now let's test the decrement method when it is called the counter value must decrease by one more. example the value of the counter is 0 when the increment is called the value of the counter must be -1. The code looks like this:

describe('Counter store', () => {
  const createStore = () => {
    const localVue = createLocalVue()
    localVue.use(Vuex)

    const store = new Vuex.Store({ state, mutations })

    return { store }
  }

  it('State => counter should start with the value zero', () => {
    const { store } = createStore()
    expect(store.state.counter).toEqual(0)
  });
  it('Mutation => should increment one more when increment is called ', () => {
    const { store } = createStore()
    store.commit('increment')
    expect(store.state.counter).toEqual(1)
    store.commit('increment')
    expect(store.state.counter).toEqual(2)
  });
it('Mutation => should decrement one more when decrement is called ', async () => {
    const { store } = createStore()
    await store.commit('decrement')
    expect(store.state.counter).toEqual(-1)
    await store.commit('decrement')
    expect(store.state.counter).toEqual(-2)
  })

})
Enter fullscreen mode Exit fullscreen mode

The last test will be to reset the value of the counter, the name of this method will be reset and when it is called, it must reset the value of the counter. Your test looked like this:

describe('Counter store', () => {
  const createStore = () => {
    const localVue = createLocalVue()
    localVue.use(Vuex)

    const store = new Vuex.Store({ state, mutations })

    return { store }
  }

  it('State => counter should start with the value zero', () => {
    const { store } = createStore()
    expect(store.state.counter).toEqual(0)
  });
  it('Mutation => should increment one more when increment is called ', () => {
    const { store } = createStore()
    store.commit('increment')
    expect(store.state.counter).toEqual(1)
    store.commit('increment')
    expect(store.state.counter).toEqual(2)
  });
it('Mutation => should decrement one more when decrement is called ', () => {
    const { store } = createStore()
    store.commit('decrement')
    expect(store.state.counter).toEqual(-1)
    store.commit('decrement')
    expect(store.state.counter).toEqual(-2)
  });
it('Mutation => should reset counter when reset is called ', () => {
    const { store } = createStore()
    store.commit('increment')
    store.commit('reset')
    expect(store.state.counter).toEqual(0)
    store.commit('decrement')
    store.commit('reset')
    expect(store.state.counter).toEqual(0)
  })

})
Enter fullscreen mode Exit fullscreen mode

the counter file code in the store folder looks like this:

export const state = () => ({
  counter: 0,
})

export const mutations = {
  increment: (state) => {
    state.counter++
  },
  decrement: (state) => {
    state.counter--
  },
  reset: (state) => {
    state.counter = 0
  },
}

export const actions = {}

export const getters = {}

Enter fullscreen mode Exit fullscreen mode

Thanks for reading the article and any questions about testing with vuex visit this site:
https://v1.test-utils.vuejs.org/guides/using-with-vuex.html
https://lmiller1990.github.io/vue-testing-handbook/vuex-in-components.html#using-createlocalvue-to-test-store-state

Discussion (2)

Collapse
luscas profile image
Lucas

Muito bom!

Collapse
fs_pauloo profile image
Paulo Author

thank you so muck, Lucas!