用 Jest 测试单文件组件

1、安装 Jest 和 Vue Test Utils

npm install --save-dev jest @vue/test-utils

2、配置 package.json

// package.json
{
"scripts": {
"test": "jest"
}
}

3、需要安装和配置 vue-jest 预处理器

npm install --save-dev vue-jest

4、在package.json 中创建一个 jest 块或在项目根目录创建 jest.config.js

module.exports = {
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub',
// 为 Jest 配置 Babel
'^.+\\.jsx?$': 'babel-jest'
},
transformIgnorePatterns: ['/node_modules/'],
// 别名
moduleNameMapper: {
'^@/(.*)$': '<rootdir>/src/$1'
},
snapshotSerializers: ['jest-serializer-vue'],
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
testURL: 'http://localhost/',
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname'
]
};

错误信息处理

1、babel 解析 es6 出错,需要配置 babel 预设


> 需要配置安装 @babel/preset-env [babel-preset-env 会有问题]

npm install --save-dev @babel/preset-env

> 配置 babel.config.js

module.exports = {
presets: [
// 使可以正常运行 vue 项目,
'@vue/app',
[
'@babel/preset-env',
{
modules: false,
}
]
],
env: {
test: {
presets: [['@babel/preset-env', { targets: { node: 'current' } }]]
}
}
}

2、npm test

> 清除缓存,然后再执行测试参考链接

最后问题还是很多,比如 UI 包的引用,webpack require.context 的问题等

然后就决定重新创建一个项目,看看有没有问题(想着官网的例子不应该是有问题的)

1、创建项目

vue create jest-demo

2、选择插件包(前一个项目大致的插件【vue-router, vuex, dart-sass, babel, eslint, unit-jest】)安装

vue-router, vuex, dart-sass, babel, eslint, unit-jest

3、写一个简单的组件('@/components/HelloWorld.vue')用做测试,简单含有一些之前项目会遇到的情况(store【如 mapGetter】、element-ui标签)

<template>
<div class="hello">
<div>{{msg}}</div>
<el-row type="flex" align="middle">
<el-col :span="4">userName</el-col>
<el-col :span="8"><el-input v-model="moduleUserName"></el-input></el-col>
</el-row>
<el-button type="primary" @click="changeUser">change user</el-button>
</div>
</template> <script>
import { mapGetters, mapMutations } from 'vuex'
export default {
name: 'HelloWorld',
props: {
msg: String,
},
data() {
return {
}
},
computed: {
...mapGetters(['storeUserName']),
moduleUserName: {
set(name) {
this.updateUserName(name)
},
get() {
return this.storeUserName
}
}
},
methods: {
...mapMutations(['updateUserName']),
changeUser() { },
}
};
</script>

4、写一个对应的测试文件

import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex'
import ElementUI from 'element-ui';
import HelloWorld from '@/components/HelloWorld.vue';
import store from '@/store' describe('HelloWorld.vue', () =&gt; {
it('renders props.msg when passed', () =&gt; {
const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(ElementUI)
const msg = 'new message';
const wrapper = shallowMount(HelloWorld, {
// 做一个数据的传
propsData: { msg },
// 使用 store
store,
// 避免混入和安装插件而污染全局 Vue
localVue,
});
expect(wrapper.text()).toMatch(msg);
});
});


OK 没有问题了,把包的配置和各文件的配置写入老再试试


5、原项目中有自动引入固定前缀的组件的插件,需要用到 webpack 的 require.context 函数对文件做检索,然后 babel-jest 是没有的,所以需要引用一个三方的插件来提供这个功能

  • 安装 babel-plugin-require-context-hook
cnpm install babel-plugin-require-context-hook
  • 在测试文件夹内创建文件 tests/unit/lib/register-context.js
import registerRequireContextHook from 'babel-plugin-require-context-hook/register';
registerRequireContextHook();
  • 在 jest.config.js 中配置 jest 预配置,使可以使用 require.context
setupFiles: ['<rootdir>/tests/unit/lib/register-context.js']
  • 在 babel.config.js 中配置 test 环境插件 require-context-hook
env: {
test: {
plugins: ['require-context-hook']
}
}

6、其他的一些设置

  • 因为项目中有引用 element-ui 和 vue-awesome,需要被 babel 解析,排除掉这两个包,在 jest.config.js 中配置
transformIgnorePatterns: [
'node_modules/(?!(element-ui|vue-awesome)/)'
],
  • 因为很多测试组件的时候需要引入很多文件或包,所以就提出来 js 文件,类似 vue 的 main.js ,做入口的统一处理,
  • 创建 tests/unit/lib/before-test.js 【基本的都是在 main.js 中引入的或添加】
// 为了方便 单元测试
// eslint-disable-next-line import/extensions
import element from '@/plugins/element'
import baseComponent from '@/plugins/base-component'
import registeSvgIcon from '@/plugins/registe-svg-icon'
import API from '@/request/api'
import axios from '@/request'
import utils from '@/utils'
jest.mock('axios')
export default (Vue) =&gt; {
element(Vue)
baseComponent(Vue)
registeSvgIcon(Vue)
Vue.prototype.$API = API
Vue.prototype.axios = axios
Vue.prototype.$util = utils
}
  • 创建 Hello.vue 组件【@/views/pages/Hello】
<template>
<div class="hello">hello</div>
</template> <script>
export default {
name: 'hello',
created() {
console.log('hello')
}
}
</script> <style lang="scss" scoped="">
.hello {}
</style>
  • 创建测试文件 tests/unit/hello.spec.js
import { shallowMount, createLocalVue } from '@vue/test-utils'
import './lib/before-test'
import Hello from '@/views/pages/Hello' describe('我是外层分组', () =&gt; {
const localVue = createLocalVue()
const wrapper = shallowMount(Hello, { localVue })
it('wrapper 是一个 vue 组件实例', () =&gt; {
expect(wrapper.isVueInstance()).toBeTruthy()
})
})


7、然后就可以学习 jest ,并用 jest 具体的添加单元测试了【虽然没有按问题来解决,但是项目添加单元测试总算OK了,先学习jest吧,再遇到问题再解决问题,结果是好的就好了~~】


  • 其他的一些问题

    原因:jsdom不支持canvas,需要额外引入包
    解决:安装jest-canvas-mock包,在jest的配置文件中添加 setupFiles: ['jest-canvas-mock']

Vue 项目添加单元测试发现的问题及解决的更多相关文章

  1. 前端单元测试,以及给现有的vue项目添加jest + Vue Test Utils的配置

    文章原址:https://www.cnblogs.com/yalong/p/11714393.html 背景介绍: 以前写的公共组件,后来需要添加一些功能,添加了好几次,每次修改我都要测试好几遍保证以 ...

  2. 如何为你的 Vue 项目添加配置 Stylelint

    如何为你的 Vue 项目添加配置 Stylelint 现在已经是 9102 年了,网上许多教程和分享帖都已经过期,照着他们的步骤来会踩一些坑,如 stylelint-processor-html 已经 ...

  3. 如何为 Vue 项目写单元测试

    https://www.w3ctech.com/topic/2052 如何为 Vue 项目写单元测试 前端工程 明非 2017-07-18 4685 访问 1 分享 微信分享 译者:明非 链接:htt ...

  4. 为 VUE 项目添加 PWA 解决发布后刷新报错问题

    为什么要给 VUE 项目添加 PWA 为什么要添加?因为不管是部署在 IIS,还是 nginx,每次应用部署后,再次访问因为旧的 js 已经不存在,所以页面访问的时候会整个报错,报错的结果就是一个白屏 ...

  5. Vue项目添加动态浏览器头部title

    0. 直接上 预览链接 + 效果图 Vue项目添加动态浏览器头部title 1. 实现思路 ( 1 ) 从路由router里面得到组件的title ( 2 ) title存vuex (本项目已经封装h ...

  6. vue中npm run dev运行项目不能自动打开浏览器! 以及 webstorm跑vue项目jshint一直提示错误问题的解决方法!

    vue中npm run dev运行项目不能自动打开浏览器!以及 webstorm跑vue项目jshint一直提示错误问题的解决方法! 1.上个项目结束就很久没有使用vue了,最近打算用vue搭建自己的 ...

  7. webpack 创建vue项目过程中遇到的问题和解决方法

    目录 1 webpack简介 2 webpack实现多个输入输出多个html 3  webpack 中的module下rules 下的use和loader选项 4 webpack 文件更新,如何使页面 ...

  8. Vs Code在Vue项目中v-for指令提示错误的解决办法

    最近在做一个Vue项目,在其中用到v-for指令时,发现Vs Code报错,如下图(代码是没有任何问题的),在网上找了一下解决办法,希望能帮助到更多人. 解决方法: 打开    文件-首选项-设置 将 ...

  9. 内网穿透访问Vue项目的时候出现Invalid Host header解决办法

    适用场景: 在本地的Vue-cli3项目, 需要其他人浏览. 如果没有外网的服务器, 可以把自己的电脑当做服务器. 这时候需要外网的人能访问到自己的电脑. Mac内网穿透工具:natapp Inval ...

随机推荐

  1. day 21

    目录 组合 封装 访问机制 property 多态 抽象类的目的 鸭子类型 组合 组合是指的是一个对象中的属性,时另一个对象. 组合的目的和继承一样,为了减少代码冗余 封装 封装指的是把一堆属性(特征 ...

  2. 从一道ctf看php反序列化漏洞的应用场景

    目录 0x00 first 前几天joomla爆出个反序列化漏洞,原因是因为对序列化后的字符进行过滤,导致用户可控字符溢出,从而控制序列化内容,配合对象注入导致RCE.刚好今天刷CTF题时遇到了一个类 ...

  3. Mybatis入门简版(二)

    一.Dao层开发的方式 以前dao层开发比较繁琐,写了接口还得写实现类,实际上用了Mybatis之后写实现类非常重复,都是重复的代码.那么此时改成另外一种简单形式. 遵循以下四个原则(名称.形参.返回 ...

  4. DataStructure之线性表以及其实现

    线性表 应用:多项式的表示 什么是线性表 多项式表示问题给出的启示: 同一个问题可以有不同的表示(存储)方法 有一类共性问题 : 有序线性序列的租住和管理 “线性表(Linear List)” : 由 ...

  5. DRF框架中csrf异常

    一.报错信息 "detail": "CSRF Failed: CSRF cookie not set." 二.解决办法 方法一: 在配置文件中配置 REST_F ...

  6. 渗透测试-基于白名单执行payload--Cmstp

    0x01 Cmstp简介 Cmstp安装或删除“连接管理器”服务配置文件.如果不含可选参数的情况下使用,则 cmstp 会使用对应于操作系统和用户的权限的默认设置来安装服务配置文件. 微软官方文档: ...

  7. ThinkPHP架构(一)-TP原理及路径问题及后台实现实例

    一直用CSDN的博客,由于域名当时注册写的不合适,现在想来博客园写博客,以后要坚持写啦,记录自己的技术学习路程 本人两个月前,刚完成基于PHP的研会门户网站,虽然实现了基本功能,但感觉技术有些单薄,便 ...

  8. PHP call_user_func的一些用法和注意点

    版本:PHP 5.6.28 在call_user_func的调用中: 1.参数的传递过程,并不是引用传值. 1 error_reporting(E_ERROR); // 此处不是E_ALL 2 $cu ...

  9. 从前端到全栈:JavaScript逆袭之路

    JavaScript如何做到上天入地无所不能?JavaScript真的能一统江湖吗? 背景 近年来,前端技术日新月异,前端已经不仅仅是网页,更多的开始由狭义向广义发展. 先后涌现出了具备后端能力的no ...

  10. 概念理解-Libevent

    可移植性: 使用 LibEvent 编写的程序应该在 LibEvent 支持跨越的所有平台上工作,即使没有更好的方法来处理. 非阻塞式IO:LibEvent也应该支持一般的方法使程序可以运行在某些限制 ...