可爱的玩笑匹配者可以使用vue-test-utils测试Vue组件

本文介绍了如何使用jest-matcher-vue-test-utils这个库来为Vue组件和Vuex模块编写直观的测试。该库提供了针对组件存在性、事件、Vuex动作/变异和道具验证等的匹配器,并且所有匹配器都带有类型定义和文档。安装后,可以在Jest测试过程中注册这些匹配器,以简化Vue组件的测试工作。
摘要由CSDN通过智能技术生成

开玩笑的匹配器测试实用程序 (jest-matcher-vue-test-utils)

Cute matchers for Jest to test Vue components with Vue Test Utils.

对于可爱的匹配玩笑测试与Vue的成分VUE考试utils的

You can write tests for Vue component/store intuitively ⚡️

您可以直观地为Vue组件/存储编写测试️

it("Emits 'select' event by clicking PrimaryButton", () => {
  const wrapper = shallowMount(Component);
  
  expect(wrapper.emitted().select).toBeUndefined();
  wrapper.find(PrimaryButton).vm.$emit("click");
  expect(wrapper.emitted().select[0]).toBeTruthy();
});

becomes

变成

it("Emits 'select' event by clicking PrimaryButton", () => {
  const wrapper = shallowMount(Component);
  
  expect(() => {
    wrapper.find(PrimaryButton).vm.$emit("click");
  }).toEmit(wrapper, "select");
});

And all matchers have type definition and doc 💇‍♂️

而且所有匹配器都有类型定义和文档💇‍♂️

jest-matcher-vue-test-utils

安装 (Installation)

Get from npm:

从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 });

提供的匹配器 (Provided Matchers)

包装上的存在 (Existence on Wrapper)

toShow (toShow)
Assert the function shows a content on Wrapper of vue-test-utils 断言该函数在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", async () => {
  return expect(async () => {
    wrapper.vm.showError();
    await wrapper.vm.$nextTick();
  }).toShow(wrapper, "p.error"); // Passes
});
toHide (toHide)
Assert the function hides a content on Wrapper of vue-test-utils 断言该函数在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", async () => {
  return expect(async () => {
    wrapper.vm.hideError();
    await wrapper.vm.$nextTick();
  }).toHide(wrapper, "p.error"); // Passes
});

包装事件 (Events on Wrapper)

toEmit (toEmit)
Assert the action emits the event (with the payload optionally) on Wrapper of vue-test-utils 断言该动作在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(wrapper, "special"); // Passes
  expect(() => wrapper.trigger("click")).toEmit(wrapper, "special", "clicked"); // Passes
});

Async function is supported as well.

也支持异步功能。

it("emits special event by click", async () => {
  const wrapper = shallowMount(Component);
  return expect(async () => triggersEventAsynchronously()).toEmit(wrapper, "special", "clicked"); // Passes
});
toHaveEmitted (toHaveEmitted)
Assert the event is emitted (with the payload optionally) on Wrapper of vue-test-utils 断言事件在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).toHaveEmitted("special"); // Passes
  expect(wrapper).toHaveEmitted("special", "clicked"); // Passes
});

Vuex动作/变异 (Vuex actions/mutations)

toDispatch (toDispatch)
Assert the function dispatches Vuex action on the component 断言函数在组件上分派Vuex操作
// click-store.vue
<template>
  <div @click="dispatchStore('click')">
    Click Me
  </div>
</template>

<script>
module.exports = {
  methods: {
    dispatchStore (e) {
      this.$store.dispatch('awesomeAction', e);
    }
  }
}
</script>
import Component from "./click-store.vue";

it("Dispatches the action on store by click", () => {
  const wrapper = shallowMount(Component);
  expect(() => {
    wrapper.trigger("click");
  }).toDispatch(wrapper, "awesomeAction"); // Passes

  expect(() => {
    wrapper.trigger("click");
  }).toDispatch(wrapper, "awesomeAction", 'click'); // Passes
});

Async function is supported as well.

也支持异步功能。

it("dispatches the action on store by click", async () => {
  return expect(async () => {
    dispatchEventAsynchronosly();
  }).toDispatch(wrapper, "awesomeAction", 'click'); // Passes
});
toCommit (TBD) (toCommit (TBD))
Assert the store mutation is committed 断言商店突变已落实
// click-store.vue
<template>
  <div @click="commitStore('click')">
    Click Me
  </div>
</template>

<script>
module.exports = {
  methods: {
    commitStore (e) {
      this.$store.commit('importantMutation', e);
    }
  }
}
</script>
import Component from "./click-store.vue";

it("Commits the mutation on store by click", () => {
  const wrapper = shallowMount(Component);
  expect(() => {
    wrapper.trigger("click");
  }).toCommit(wrapper, "importantMutation"); // Passes

  expect(() => {
    wrapper.trigger("click");
  }).toCommit(wrapper, "importantMutation", 'click'); // Passes
});
toHaveDispatched (toHaveDispatched)
Assert a component has dispatched Vuex action 断言组件已调度Vuex操作
// click-store.vue
<template>
  <div @click="dispatchStore('click')">
    Click Me
  </div>
</template>

<script>
module.exports = {
  methods: {
    dispatchStore (e) {
      this.$store.dispatch('awesomeAction', e);
    }
  }
}
</script>
import Component from "./click-store.vue";
import { vuexPlugin } from "jest-matcher-vue-test-utils";

it("Dispatches the action on store by click", () => {
  const store = new Vuex.Store({
    actions: dispatchStore() {},
    plugins: [vuexPlugin()] // Requires adding plugin to use `toHaveDispatched` matcher
  });

  const wrapper = shallowMount(Component, { store })
  wrapper.trigger("click");
  expect(wrapper).toHaveDispatched("awesomeAction"); // Passes
  expect(wrapper).toHaveDispatched("awesomeAction", "click"); // Passes
});

道具验证 (Prop Validations)

toBeValidProps (toBeValidProps)
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
});
toBeValidProp (toBeValidProp)
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
});
toRequireProp (toRequireProp)
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
});
toHaveDefaultProp (toHaveDefaultProp)
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
});
toBeValidPropWithTypeCheck (toBeValidPropWithTypeCheck)
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
});
toBeValidPropWithCustomValidator (toBeValidPropWithCustomValidator)
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
});

设定档 (Config)

We can configure the matchers. Currently accepting mountOptions property to give options for shallowMount which is running in inside of matchers.

我们可以配置匹配器。 当前接受mountOptions属性来为在匹配器内部运行的shallowMount提供选项。

import vueTestUtilMatchers, { config } from "jest-matcher-vue-test-utils";
import { createLocalVue } from "@vue/test-utils";

config({
  mountOptions: { localVue: createLocalVue() }
});

翻译自: https://vuejsexamples.com/cute-jest-matchers-to-test-vue-components-with-vue-test-utils/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值