Unit Testing Vue Lifecycle Methods
Testing Vue components is incredibly simple. However, lifecycle methods are almost always overlooked.
Testing Vue components is incredibly simple. However, lifecycle methods are almost always overlooked. While testing lifecycle methods isn't difficult, I haven't found too many resources out there that explain how to do this.
Writing the Component
First, let's say we have a component called MyLifecycleComponent.vue
. This component calls an initialize
method during the mounted
lifecycle step:
<template>
<div>Hello lifecycle component!</div>
</template>
<script>
export default {
name: 'MyLifecycleComponent',
methods: {
initialize() {
console.log('initialized');
}
},
mounted() {
this.initialize();
}
}
</script>
A very basic test would be to check whether the initialize()
method gets called during the mounted()
lifecycle.
Writing the Test
By default, lifecycle methods are called automatically while the component is being created, therefore they're supposed to be called only once.
What I want to do is to make the lifecycle methods callable inside the tests. The component instance wrapper.vm
does not expose lifecycle methods by default, therefore we need to add them when mounting the component wrapper
.
let wrapper;
beforeEach(() => {
wrapper = shallowMount(MyLifecycleComponent, {
methods: {
mounted: MyLifecycleComponent.mounted
}
});
});
It's good practice to mount the component before each test in order to have a clean state. As a rule of thumb, it's best to keep things as simple as possible, that's why we're not testing the actual effect of the initialize
method, but whether it has been called.
In order to check whether a method has been called, we use jest.spyOn()
to create a spy. The spy contains information on whether the method has been called or not, how many times it has been called, and what it has been called with.
import MyLifecycleComponent from '@/components/MyLifecycleComponent';
import { shallowMount } from '@vue/test-utils';
describe('MyLifecycleComponent', () => {
let wrapper;
beforeEach(() => {
wrapper = shallowMount(MyLifecycleComponent, {
methods: {
mounted: MyLifecycleComponent.mounted
}
});
});
describe('mounted()', () => {
it('should call initialize method', () => {
const spy = jest.spyOn(wrapper.vm, 'initialize');
wrapper.vm.mounted();
expect(spy).toHaveBeenCalled();
});
});
});
Conclusion
Testing lifecycle methods is hassle free when you know how to do it. All of the code presented here can be found in this repository.
When unit testing, I always aim for a 100% test coverage because it keeps me out of trouble when I refactor my code.
PASS tests/unit/MyLifecycleComponent.spec.js
MyLifecycleComponent
mounted()
✓ should call initialize method (27ms)
console.log src/components/MyLifecycleComponent.vue:10
initialized
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.051s
Ran all test suites.