# On existing Vue CLI project
vue add unit-jest
# Anywhere
npm install --save-dev @vue/test-utils vue-jest
# OR
yarn add -D @vue/test-utils vue-jest
npm install --save-dev jest
# OR
yarn add -D jest
npm install --save-dev babel-jest @babel/core @babel/preset-env
# OR
yarn add -D babel-jest @babel/core @babel/preset-env
// babel.config.js
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};
npm install --save-dev @vue/test-utils vue-jest
# OR
yarn add -D @vue/test-utils vue-jest
// package.json
{
"jest": {
"moduleFileExtensions": [
"js",
"json",
// tell Jest to handle `*.vue` files
"vue"
],
"transform": {
// process `*.vue` files with `vue-jest`
".*\\.(vue)$": "vue-jest"
}
}
}
// MyComponent.spec.js
import { shallowMount } from "@vue/test-utils";
import MyComponent from "@/components/MyComponent.vue";
describe("MyComponent", () => {
let wrapper;
it("is a Vue component", () => {
wrapper = shallowMount(MyComponent);
expect(wrapper.exists()).toBe(true);
});
});
// MyComponent.spec.js
// component factory
function createComponent() {
wrapper = shallowMount(MyComponent);
}
// destroying a wrapper
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
// MyComponent.spec.js
it('does not render title when showTitle prop is false', () => {
createComponent()
expect(wrapper.find("[data-testid='title']").exists()).toBe(false)
})
function createComponent(props = {}) {
wrapper = shallowMount(MyComponent, {
propsData: {
...props,
},
})
}
...
createComponent({ showTitle: true })
let wrapper
const findTitle = () => wrapper.find("[data-testid='title']")
const findTitle = () => wrapper.find("[data-testid='title']")
const findIncrementButton = () => wrapper.find('.test-increment-button')
...
it('increments count on increment button click', () => {
createComponent()
expect(findCount().text()).toBe('Count: 0')
findIncrementButton().trigger('click')
})
const findTitle = () => wrapper.find("[data-testid='title']")
const findIncrementButton = () => wrapper.find('.test-increment-button')
...
it('increments count on increment button click', async () => {
createComponent()
expect(findCount().text()).toBe('Count: 0')
findIncrementButton().trigger('click')
await wrapper.vm.$nextTick
expect(findCount().text()).toBe('Count: 1')
})
it('renders a correct doubled value', () => {
createComponent()
expect(findDoubleCount().text()).toContain('0')
})
function createComponent(props = {}, data = {}) {
wrapper = shallowMount(MyComponent, {
propsData: {
...props,
},
data() {
return {
...data,
}
},
})
}
it('renders a correct doubled value', () => {
createComponent({}, { count: 3 })
expect(findDoubleCount().text()).toContain('6')
})
it('emits a custom event on emitter button click', () => {
createComponent()
wrapper.find('.test-emitter').trigger('click')
expect(wrapper.emitted('custom-event')).toBeTruthy()
expect(wrapper.emitted('custom-event')).toEqual([['Hello World']])
})
it('emits an event on showTitle change', async () => {
createComponent()
wrapper.setProps({ showTitle: true })
await wrapper.vm.$nextTick
expect(wrapper.emitted('watcher-triggered')).toBeTruthy()
})
it('changes childCounter on MyButton click', async () => {
createComponent()
wrapper.findComponent(MyButton).vm.$emit('click')
await wrapper.vm.$nextTick()
expect(findChildCounter().text()).toContain('2')
})
function createComponent(props = {}, data = {}) {
wrapper = shallowMount(MyComponent, {
propsData: {
...props,
},
data() {
return {
...data,
}
},
mocks: {
$route: {
path: '/',
},
},
stubs: ['router-link'],
})
}
import { shallowMount, mount, createLocalVue } from '@vue/test-utils'
const localVue = createLocalVue()
localVue.use(VueRouter)
const router = new VueRouter({
routes: [{ path: '/', component: MyComponent }],
})
function createComponent(props = {}, data = {}) {
wrapper = shallowMount(MyComponent, {
localVue,
router,
...
})
}