How to unit test a Vue.js / Nuxt.js component that uses <nuxt-link> and store
// Minimal Webpack config to supply to units tests.
// This is not actually used by Nuxt but instead mirrors
// the resolve and loader rules.
const resolve = require('path').resolve;
// resolve to absolute path where "npm test" is running from
const root = resolve('.')
module.exports = {
resolve: {
modules: [root + '/node_modules'],
extensions: ['.js', '.vue'],
alias: {
'~': root,
'static': root + '/static', // use in template with <img src="~static/nuxt.png" />
'~static': root + '/static',
'assets': root + '/assets', // use in template with <img src="~static/nuxt.png" />
'~assets': root + '/assets',
'~plugins': root + '/plugins',
'~store': root + '/.nuxt/store',
'~router': root + '/.nuxt/router',
'~pages': root + '/pages',
'~components': root + '/components',
'~lib': root + '/lib',
}
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.vue$/,
exclude: /node_modules/,
loader: 'vue-loader',
}
]
}
};
<template>
<div class="container">
<nav class="nav">
<div class="nav-left">
<span class="nav-item">
UMAMI food magazine <br />
<AppVersion />
</span>
</div>
<!-- This "nav-toggle" hamburger menu is only visible on mobile -->
<!-- You need JavaScript to toggle the "is-active" class on "nav-menu" -->
<span class="nav-toggle" @click="setMenuMobileIsOpened">
<span></span>
<span></span>
<span></span>
</span>
<!-- This "nav-menu" is hidden on mobile -->
<!-- Add the modifier "is-active" to display it on mobile -->
<div class="nav-right nav-menu" :class="{'is-active': this.$store.state.menuMobileIsOpened}">
<nuxt-link to="/" class="nav-item"> Home </nuxt-link>
<nuxt-link to="/recipes" class="nav-item"> Recipes </nuxt-link>
<!--<nuxt-link @click.native="displayMobileMenu = false" to="/magazine" class="nav-item"> Magazine </nuxt-link>-->
</div>
</nav>
</div>
</template>
<script>
import AppVersion from '~/components/AppVersion'
export default {
components: { AppVersion },
methods: {
setMenuMobileIsOpened() {
this.$store.commit('setMenuMobileIsOpened', !this.$store.state.menuMobileIsOpened)
}
}
}
</script>
<style scoped>
.nuxt-link-exact-active {
color:#363636;
}
</style>
import Vue from 'vue'
import AppNavigation from '~/components/AppNavigation'
// Mock our router, store and nuxt-link
import Vuex from 'vuex'
import storeCreate from '~/store'
import VueRouter from 'vue-router'
import NuxtLink from '~/.nuxt/components/nuxt-link'
Vue.use(VueRouter)
Vue.use(Vuex)
/**
* An example unit test
*/
describe('AppNavigation.vue', () => {
let vm = null
beforeEach(() => {
// Inject manually Nuxt-link to avoid an error message
AppNavigation.components.NuxtLink = NuxtLink
const Constructor = Vue.extend(AppNavigation)
vm = new Constructor({ router: new VueRouter() })
vm.$store = storeCreate()
vm.$mount()
})
it('Mobile menu should have a is-active class when $store.state.menuMobileIsOpened == true', () => {
expect(vm.$el.querySelector('.nav-right').className.trim()).toBe('nav-right nav-menu')
vm.setMenuMobileIsOpened()
// we should now have an active class on next DOM update
vm.$nextTick(() => {
expect(vm.$el.querySelector('.nav-right').className.trim()).toBe('nav-right nav-menu is-active')
})
})
})