Cute matchers for Jest to test Vue components with Vue Test Utils.
Get from npm:
$ npm install -D jest-matcher-vue-test-utils
Then, register matchers on your jest process:
import vueTestUtilMatchers from "jest-matcher-vue-test-utils";
expect.extend({ ...vueTestUtilMatchers });
Assert the action shows a content on Wrapper of vue-test-utils
// error-message.vue
<template>
<div>
<p v-if="isError" class="error">message</p>
</div>
</template>
...
data: function () {
return {
isError: false
}
},
methods: {
showError () {
this.isError = true;
}
}
import Component from "./error-message.vue";
it("show error by showError", () => {
expect(() => wrapper.vm.showError()).toShow(wrapper, "p.error"); // Passes
});
Assert the action hides a content on Wrapper of vue-test-utils
// error-message.vue
<template>
<div>
<p v-if="isError" class="error">message</p>
</div>
</template>
...
data: function () {
return {
isError: true
}
},
methods: {
hideError () {
this.isError = false;
}
}
import Component from "./error-message.vue";
it("show error by showError", () => {
expect(() => wrapper.vm.hideError()).toHide(wrapper, "p.error"); // Passes
});
Assert the action emits the event (with the payload optionally) on Wrapper of vue-test-utils
// event.vue
<template>
<div @click="emitEvent('clicked')">
Click Me
</div>
</template>
<script>
module.exports = {
methods: {
emitEvent (e) {
this.$emit("special", e);
}
}
}
</script>
import Component from "./event.vue";
it("emits special event by click", () => {
const wrapper = shallowMount(Component);
expect(() => wrapper.trigger("click")).toEmit("special"); // Passes
expect(() => wrapper.trigger("click")).toEmit("special", "clicked"); // Passes
});
Assert the event is emitted (with the payload optionally) on Wrapper of vue-test-utils
// event.vue
<template>
<div @click="emitEvent('clicked')">
Click Me
</div>
</template>
<script>
module.exports = {
methods: {
emitEvent (e) {
this.$emit("special", e);
}
}
}
</script>
import Component from "./event.vue";
it("emits special event by click", () => {
const wrapper = shallowMount(Component);
wrapper.trigger("click");
expect(wrapper).toBeEmitted("special"); // Passes
expect(wrapper).toBeEmitted("special", "clicked"); // Passes
});
Assert that a prop set is valid for a component
// name-require-and-fullname-is-validated-component.vue
props: {
name: {
type: String,
required: true
}
fullname: {
validator: function (val) {
return !!val && val.match(/.+\s.+/);
}
}
}
import Component from "./name-require-and-fullname-is-validated-component.vue";
it("component validates props", () => {
expect(Component).toBeValidProps({ name: "required name", fullName: "Kengo Hamasaki" }); // Passes
expect(Component).toBeValidProps({ fullName: "Kengo Hamasaki" }); // Fails
expect(Component).toBeValidProps({ name: "required name", fullName: "Kengo" }); // Fails
});
Assert that a single prop is valid for a component
// name-require-component.vue
props: {
name: {
type: String,
required: true
}
}
import Component from "./name-require-component.vue";
it("component validates props", () => {
expect(Component).toBeValidProp("name", "Required Name"); // Passes
expect(Component).toBeValidProp("name", null); // Fails as required
expect(Component).toBeValidProp("name", 123}); // Fails as typecheck
});
Assert that a component requires a prop
// name-require-component.vue
props: {
name: {
type: String,
required: true
}
}
import Component from "./name-require-component.vue";
it("component requires name prop", () => {
expect(Component).toRequireProp("name"); // Passes
expect(Component).toRequireProp("birthday"); // Fails
});
Assert that a component gives default to a prop
// default-address-component.vue
props: {
address: {
type: String,
default: "Kitakyushu, Japan"
}
}
import Component from "./default-address-component.vue";
it("component gives default value for address prop", () => {
expect(Component).toHaveDefaultProp("address", "Kitakyushu, Japan"); // Passes
expect(Component).toHaveDefaultProp("address", "San Francisco, US"); // Fails
});
Assert that a component validates a prop with type
// takes-zipcode-component.vue
props: {
zipcode: {
type: String
}
}
import Component from "./takes-zipcode-component.vue";
it("component validates zipcode prop", () => {
expect(Component).toBeValidPropWithTypeCheck("zipcode", "94103"); // Passes
expect(Component).toBeValidPropWithTypeCheck("zipcode", 94103); // Fails
});
Assert that a component validates a prop with custom validator
// fullname-is-validated-component.vue
props: {
fullname: {
validator: function (val) {
return !!val && val.match(/.+\s.+/);
}
}
}
import Component from "./fullname-is-validated-component.vue";
it("component validates fullname prop", () => {
expect(Component).toBeValidPropWithCustomValidator("fullname", "Kengo Hamasaki"); // Passes
expect(Component).toBeValidPropWithCustomValidator("fullname", "Kengo"); // Fails
});
We can configure the matchers. Currently accepting mountOptions property to give options for shallowMount
which is running in inside of matchers.
import vueTestUtilMatchers, { config } from "jest-matcher-vue-test-utils";
import { createLocalVue } from "@vue/test-utils";
config({
mountOptions: { localVue: createLocalVue() }
});
MIT, Copyright (c) 2018 Kengo Hamasaki