Testing logic inside a Vue.js watcher
Even though the most of the time we use computed properties to react to data changes, sometimes we have to use a watcher in order to perform an expensive operation or an asynchronous call to our API. Let's keep it simple for this example.
Imagine that you have a component that emits an input event when an internal value changes:
<template>
<input v-model="internalValue" />
</template>
<script>
export default {
data() {
return {
internalValue: ""
};
},
watch: {
internalValue(value) {
this.$emit("input", value);
}
}
};
</script>
When its time to test this feature, the first thing that comes to our minds is that we have to mount the component, change the internalValue data and expect that the watcher has been fired.
But you know what? That feature is already tested by Vue core members. Don't do it again. Evan You is pretty confident that a watcher is fired when its associated value changes.
You can do a test like this instead:
test("emits input event when interalValue changes", () => {
const wrapper = shallowMount(YourComponent);
wrapper.vm.$options.watch.internalValue.call(wrapper.vm, 15);
expect(wrapper.emitted("input")[0][0]).toBe(15);
});
Vue attaches to the $options.watch
object each watcher that we define in our component so what we are doing here is invoking the watcher directly using call()
.
First parameter of call
is the context of this
inside the function (the component instance). Then we can pass more parameters (the value).
So wrapping up: "Don't test the framework"
Sometimes is hard to identify the code that you own from the features that have already been tested thousands of times by the library you are using. I guarantee you that a watcher is going to be fired when the data is changed.
Test the logic inside of it, don't waste your precious time trying to re-create the scenario and the conditions that would fire the watcher up.
Related Articles
Hybrid Rendering: the secret way to smoothly test Vue.js components
Find out how to combine Deep and Shallow Rendering in order to achieve a flexible solution to test your Vue.js combining the best of both worlds.
Mar 7, 2022
Deep vs Shallow Rendering in Vue.js Tests
A short article on how to use deep and shallow rendering in Vue.js and what I suggest to use most of the cases using vue test utils.
Mar 3, 2020
Quick Content Testing using Snapshots in Vue.js
Useful tip about how to use snapshot testing in Vue.js the right way and have consistent and coherent tests in your applications
May 28, 2019
Sponsors
VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.