Gathering detailed insights and metrics for jest-matcher-vue-test-utils
Gathering detailed insights and metrics for jest-matcher-vue-test-utils
Gathering detailed insights and metrics for jest-matcher-vue-test-utils
Gathering detailed insights and metrics for jest-matcher-vue-test-utils
✨ Cute jest matchers to test Vue components with vue-test-utils
npm install jest-matcher-vue-test-utils
Typescript
Module System
Node Version
NPM Version
TypeScript (100%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
33 Stars
720 Commits
3 Forks
2 Watchers
19 Branches
3 Contributors
Updated on Sep 29, 2023
Latest Version
2.0.1
Package Id
jest-matcher-vue-test-utils@2.0.1
Unpacked Size
42.94 kB
Size
8.62 kB
File Count
20
NPM Version
6.14.5
Node Version
12.16.1
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
2
Cute matchers for Jest to test Vue components with Vue Test Utils.
You can write tests for Vue component/store intuitively ⚡️
1it("Emits 'select' event by clicking PrimaryButton", () => { 2 const wrapper = shallowMount(Component); 3 4 expect(wrapper.emitted().select).toBeUndefined(); 5 wrapper.find(PrimaryButton).vm.$emit("click"); 6 expect(wrapper.emitted().select[0]).toBeTruthy(); 7});
becomes
1it("Emits 'select' event by clicking PrimaryButton", () => { 2 const wrapper = shallowMount(Component); 3 4 expect(() => { 5 wrapper.find(PrimaryButton).vm.$emit("click"); 6 }).toEmit(wrapper, "select"); 7});
And all matchers have type definition and doc 💇♂️
Get from npm:
1$ npm install -D jest-matcher-vue-test-utils
Then, register matchers on your jest process:
1import vueTestUtilMatchers from "jest-matcher-vue-test-utils"; 2expect.extend({ ...vueTestUtilMatchers });
toShow
1// error-message.vue 2<template> 3 <div> 4 <p v-if="isError" class="error">message</p> 5 </div> 6</template> 7 8... 9 10data: function () { 11 return { 12 isError: false 13 } 14}, 15methods: { 16 showError () { 17 this.isError = true; 18 } 19}
1import Component from "./error-message.vue"; 2 3it("show error by showError", async () => { 4 return expect(async () => { 5 wrapper.vm.showError(); 6 await wrapper.vm.$nextTick(); 7 }).toShow(wrapper, "p.error"); // Passes 8});
toHide
1// error-message.vue 2<template> 3 <div> 4 <p v-if="isError" class="error">message</p> 5 </div> 6</template> 7 8... 9 10data: function () { 11 return { 12 isError: true 13 } 14}, 15methods: { 16 hideError () { 17 this.isError = false; 18 } 19}
1import Component from "./error-message.vue"; 2 3it("show error by showError", async () => { 4 return expect(async () => { 5 wrapper.vm.hideError(); 6 await wrapper.vm.$nextTick(); 7 }).toHide(wrapper, "p.error"); // Passes 8});
toEmit
/ toEmitOnRoot
1// event.vue 2<template> 3 <div @click="emitEvent('clicked')"> 4 Click Me 5 </div> 6</template> 7 8<script> 9module.exports = { 10 methods: { 11 emitEvent (e) { 12 this.$emit("special", e); 13 } 14 } 15} 16</script>
1import Component from "./event.vue"; 2 3it("emits special event by click", () => { 4 const wrapper = shallowMount(Component); 5 expect(() => wrapper.trigger("click")).toEmit(wrapper, "special"); // Passes 6 expect(() => wrapper.trigger("click")).toEmit(wrapper, "special", "clicked"); // Passes 7});
Async function is supported as well.
1it("emits special event by click", async () => { 2 const wrapper = shallowMount(Component); 3 return expect(async () => triggersEventAsynchronously()).toEmit(wrapper, "special", "clicked"); // Passes 4});
toEmitOnRoot
inspects whether the event is emitted on $root
of Vue instance.
toHaveEmitted
/ toHaveEmittedOnRoot
1// event.vue 2<template> 3 <div @click="emitEvent('clicked')"> 4 Click Me 5 </div> 6</template> 7 8<script> 9module.exports = { 10 methods: { 11 emitEvent (e) { 12 this.$emit("special", e); 13 } 14 } 15} 16</script>
1import Component from "./event.vue"; 2 3it("emits special event by click", () => { 4 const wrapper = shallowMount(Component); 5 wrapper.trigger("click"); 6 expect(wrapper).toHaveEmitted("special"); // Passes 7 expect(wrapper).toHaveEmitted("special", "clicked"); // Passes 8});
toHaveEmittedOnRoot
inspects whether the event is emitted on $root
of Vue instance.
toDispatch
1// click-store.vue 2<template> 3 <div @click="dispatchStore('click')"> 4 Click Me 5 </div> 6</template> 7 8<script> 9module.exports = { 10 methods: { 11 dispatchStore (e) { 12 this.$store.dispatch('awesomeAction', e); 13 } 14 } 15} 16</script>
1import Component from "./click-store.vue"; 2 3it("Dispatches the action on store by click", () => { 4 const wrapper = shallowMount(Component); 5 expect(() => { 6 wrapper.trigger("click"); 7 }).toDispatch(wrapper, "awesomeAction"); // Passes 8 9 expect(() => { 10 wrapper.trigger("click"); 11 }).toDispatch(wrapper, "awesomeAction", 'click'); // Passes 12});
Async function is supported as well.
1it("dispatches the action on store by click", async () => { 2 return expect(async () => { 3 dispatchEventAsynchronosly(); 4 }).toDispatch(wrapper, "awesomeAction", 'click'); // Passes 5});
toCommit
(TBD)1// click-store.vue 2<template> 3 <div @click="commitStore('click')"> 4 Click Me 5 </div> 6</template> 7 8<script> 9module.exports = { 10 methods: { 11 commitStore (e) { 12 this.$store.commit('importantMutation', e); 13 } 14 } 15} 16</script>
1import Component from "./click-store.vue"; 2 3it("Commits the mutation on store by click", () => { 4 const wrapper = shallowMount(Component); 5 expect(() => { 6 wrapper.trigger("click"); 7 }).toCommit(wrapper, "importantMutation"); // Passes 8 9 expect(() => { 10 wrapper.trigger("click"); 11 }).toCommit(wrapper, "importantMutation", 'click'); // Passes 12});
toHaveDispatched
1// click-store.vue 2<template> 3 <div @click="dispatchStore('click')"> 4 Click Me 5 </div> 6</template> 7 8<script> 9module.exports = { 10 methods: { 11 dispatchStore (e) { 12 this.$store.dispatch('awesomeAction', e); 13 } 14 } 15} 16</script>
1import Component from "./click-store.vue"; 2import { vuexPlugin } from "jest-matcher-vue-test-utils"; 3 4it("Dispatches the action on store by click", () => { 5 const store = new Vuex.Store({ 6 actions: dispatchStore() {}, 7 plugins: [vuexPlugin()] // Requires adding plugin to use `toHaveDispatched` matcher 8 }); 9 10 const wrapper = shallowMount(Component, { store }) 11 wrapper.trigger("click"); 12 expect(wrapper).toHaveDispatched("awesomeAction"); // Passes 13 expect(wrapper).toHaveDispatched("awesomeAction", "click"); // Passes 14});
toBeValidProps
1// name-require-and-fullname-is-validated-component.vue 2props: { 3 name: { 4 type: String, 5 required: true 6 } 7 fullname: { 8 validator: function (val) { 9 return !!val && val.match(/.+\s.+/); 10 } 11 } 12}
1import Component from "./name-require-and-fullname-is-validated-component.vue";
2
3it("component validates props", () => {
4 expect(Component).toBeValidProps({ name: "required name", fullName: "Kengo Hamasaki" }); // Passes
5 expect(Component).toBeValidProps({ fullName: "Kengo Hamasaki" }); // Fails
6 expect(Component).toBeValidProps({ name: "required name", fullName: "Kengo" }); // Fails
7});
toBeValidProp
1// name-require-component.vue 2props: { 3 name: { 4 type: String, 5 required: true 6 } 7}
1import Component from "./name-require-component.vue";
2
3it("component validates props", () => {
4 expect(Component).toBeValidProp("name", "Required Name"); // Passes
5 expect(Component).toBeValidProp("name", null); // Fails as required
6 expect(Component).toBeValidProp("name", 123}); // Fails as typecheck
7});
toRequireProp
1// name-require-component.vue 2props: { 3 name: { 4 type: String, 5 required: true 6 } 7}
1import Component from "./name-require-component.vue"; 2 3it("component requires name prop", () => { 4 expect(Component).toRequireProp("name"); // Passes 5 expect(Component).toRequireProp("birthday"); // Fails 6});
toHaveDefaultProp
1// default-address-component.vue 2props: { 3 address: { 4 type: String, 5 default: "Kitakyushu, Japan" 6 } 7}
1import Component from "./default-address-component.vue"; 2 3it("component gives default value for address prop", () => { 4 expect(Component).toHaveDefaultProp("address", "Kitakyushu, Japan"); // Passes 5 expect(Component).toHaveDefaultProp("address", "San Francisco, US"); // Fails 6});
toBeValidPropWithTypeCheck
1// takes-zipcode-component.vue 2props: { 3 zipcode: { 4 type: String 5 } 6}
1import Component from "./takes-zipcode-component.vue"; 2 3it("component validates zipcode prop", () => { 4 expect(Component).toBeValidPropWithTypeCheck("zipcode", "94103"); // Passes 5 expect(Component).toBeValidPropWithTypeCheck("zipcode", 94103); // Fails 6});
toBeValidPropWithCustomValidator
1// fullname-is-validated-component.vue 2props: { 3 fullname: { 4 validator: function (val) { 5 return !!val && val.match(/.+\s.+/); 6 } 7 } 8}
1import Component from "./fullname-is-validated-component.vue"; 2 3it("component validates fullname prop", () => { 4 expect(Component).toBeValidPropWithCustomValidator("fullname", "Kengo Hamasaki"); // Passes 5 expect(Component).toBeValidPropWithCustomValidator("fullname", "Kengo"); // Fails 6});
We can configure the matchers. Currently accepting mountOptions property to give options for shallowMount
which is running in inside of matchers.
1import vueTestUtilMatchers, { config } from "jest-matcher-vue-test-utils"; 2import { createLocalVue } from "@vue/test-utils"; 3 4config({ 5 mountOptions: { localVue: createLocalVue() } 6});
MIT, Copyright (c) 2018- Kengo Hamasaki
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
Found 0/9 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
license file not detected
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
29 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More