vue-test-utils初使用详解

vue-test-utils官网:https://vue-test-utils.vuejs.org/zh/

jest官网:https://jestjs.io

依赖包

请安装它们👇

yarn add @vue/test-utils vue-jest
yarn jestjest-serializer-vue
yarn add babel-jest babel-core@^7.0.0-bridge.0

⚠️:vue-jest依赖与babel-core。我们的环境现在都是babel7,通过npm安装的babel-core默认的还是6版本,所以要指定babel-core安装的系列为7,否则会出现解析问题。

配置

jest配置:告诉jest它需要哪些额外的配置

jest相关的配置可以配置在package.json中或者单独的jest.config.json文件中:

// jest.config.json
{
  "moduleFileExtensions": [
    "js",
    "json",
    "vue"
  ],
  "transform": {
    "^.+\\.js$": "<rootDir>/node_modules/babel-jest", // jest使用babel解析js
    ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest" // jest对vue单文件的解析
  },
  "snapshotSerializers": [
    "<rootDir>/node_modules/jest-serializer-vue"
   ],
  "moduleNameMapper": {
    "^@/(.*)$": "<rootDir>/src/$1", //为了解析webpack配置的alias字段
    "^tim-architect/(.*)$": "<rootDir>/tim-architect/$1"
  },
  "transformIgnorePatterns": [
    "node_modules/(?!(yourModuleName))"
  ]
}

⚠️:transformIgnorePatterns的默认配置是["node_modules"],表示所有的node_modules下的包都不需要babel解析。但是一些3rd库提供的文件仍然是未编译的es6语法,jest在解析时会报语法错误。因此需要指定白名单,需要那些node_modules下的包被babel转换。

babel配置:告诉babel你需要用哪些工具去处理一坨(💩香么 ?💩 : 💩 )代码

推荐使用babel.config.js(babel需要转换的node_modules同样生效)而不是.babelrc(当前项目生效)。

{
  ...,
 env: {
  test: {
   presets: [[
    '@babel/env',
    {
     modules: 'auto', // 现在不能通过webpack来解析s6 module,需要使用babel来解析,所以要开启
     targets: {
      node: 'current' // 指定环境为当前node版本,减少解析不识别语法的范围
     }
    }
   ]],
   plugins: [[
    '@babel/plugin-transform-runtime', {
     corejs: 2,
     useESModules: false // 不允许使用es modules,babel需要通过@babel/plugin-transform-modules-commonjs将es module转换为commonjs模块解析
    }
   ]
  ]
 }
 }
}

⚠️:通过babel的env.test指定jest测试时需要的babel配置(同webpack转换解析时不同),jest会自动识别env.test的配置。

单测文件

理解:

  • 单元测试不应该追求代码的覆盖率;
  • 单元测试主要是为了测试组件UI,数据驱动后UI的变化在可控范围之内;
  • 测试组件应以纯组件为主(业务组件逻辑过于复杂或经常变动,涉及到的引入文件过多,不便于测试所有的功能性),纯组件作为项目的基础组件功能性上基本不变化。

遇到的问题总结

1.异步生命周期

vue-test-utils提供了对异步请求方法的mock,文档如下:https://vue-test-utils.vuejs.org/zh/guides/testing-async-components.html

但是对于生命周期函数是异步的情况要怎么处理呢?以下是亲测有效但是有点麻烦的姿势:

// 假设在异步生命周期方法中,调用的函数是init,那我们就通过jest.fn()提供的方法进行mock
init.default = jest.fn().mockImplementation(() => Promise.resolve(yourValue))

// 在Jest提供的全局方法中,调用异步生命周期的方法,以保证每个断言都是在生命周期之后
beforeEach(async () => {
 init.default.mockClear()
 await wrapper.vm.$mount() // 异步生命周期里会调用init方法
})

2.如果测试文件中包含require.context,请看这一条 :

这时候没有webpack怎么办?当然是用别人踩过坑的方法救急!

说实话,如果组件引用了这种东西,我觉得它不够纯洁,还是不要管它好了╮( ̄⊿ ̄")╭,放它走吧。

但是为什么要解决这个问题呢?想到以后可能还要测试js文件,我们的标准也有可能是覆盖代码行数的测试,所以,还是解决一下吧。

其实思路很简单,我们需要在全局重写require.context,babel再遇到require.context就不会报错了。

// 别怕,不需要你手动写,有人已经写了个插件了:babel-plugin-require-context-hook
// 在babel.config.js的env.test中加上这个插件
...
plugins: [..., 'require-context-hook']
...

// 在jest.config.json中配置一下setupFiles
// setupFiles表示在每个运行文件前添加的额外配置
...
"setupFiles": ["<rootDir>/.jest/register-context.js"],
...

// 创建.jest/register-context.js文件,引入时进行全局的注册
import registerRequireContextHook from 'babel-plugin-require-context-hook/register';
registerRequireContextHook();

3.测试过程总是报synax error ,诸如import无法解析这类es6语法引起的错误

小兄弟,只能说好好检查一下你的babel是否配置正确,并且安装了适合的babel-core版本。出现这个问题的时候,说明babel并没有解析es6语法,顺藤摸瓜,

(确保依赖包的安装源相同,建议用yarn)

  • if 是node_modules里的文件导致的,通过配置transformIgnorePatterns告诉babel需要它解析的模块;
  • else if 是项目的文件导致的,那就查看下自己的babel.config.js(确保不是.babelrc文件)是否配置正确,如果使用了@babel/preset-env,请注意module参数的配置;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解在vue-test-utils中mock全局对象

    vue-test-utils   提供了一种 mock 掉   Vue.prototype   的简单方式,不但对测试用例适用,也可以为所有测试设置默认的 mock. mocks   加载选项 mocks   加载选项   是一种将任何属性附加到   Vue.prototype   上的方式.这通常包括: $store , for Vuex $router , for Vue Router $t , for vue-i18n 以及其他种种. vue-i18n   的例子 我们来看一个 vue-i

  • vue移动端屏幕适配详解

    flexible vue移动端屏幕适配,查看项目地址 效果预览 # 项目clone git clone git@github.com:NicolasGui/flexible.git # 进入项目目录 cd flexible # 安装依赖 npm install # 启动服务 localhost:8080 npm run dev 原理概述 插件安装 # 插件一:amfe-flexible npm install amfe-flexible --save #  插件二: node-sass npm

  • 代号为Naruto的Vue 2.7正式发布功能详解

    目录 引言 向后移植的功能 注意事项 与 Vue 3 的行为差异 升级指南 Vue CLI / webpack Vite Volar 兼容性 Devtools 支持 2.7 版本的影响 额外细节 引言 Vue 正式发布了 2.7 版本, 版本名称为 Naruto,即火影忍者. 尽管现在 Vue 3 是默认版本,但由于仍有许多用户由于依赖兼容性.浏览器支持要求或没有足够的带宽升级而不得不继续使用 Vue 2.在 Vue 2.7 中,从 Vue 3 向后移植了一些最重要的功能,以便 Vue 2 用户

  • Vue websocket封装实现方法详解

    目录 1.封装的ws.js文件 2.使用方法 1.封装的ws.js文件 let global_callback = null let socket = '' // 存储 WebSocket 连接. let timeoutObj = null // 心跳定时器 let serverTimoutObj = null // 服务超时定时关闭 let lockReconnect = false // 是否真正建立了连接 let timeoutnum = null // 重新连接的定时器, 没连接上会一直

  • vue系列之动态路由详解【原创】

    开题 最近用vue来构建了一个小项目,由于项目是以iframe的形式嵌套在别的项目中的,所以对于登录的验证就比较的麻烦,索性后端大佬们基于现在的问题提出了解决的方案,在看到他们的解决方案之前,我先画了一个比较标准的单系统的解决方案. 本文目录: 一: 设想 二: 讨论 三:实现 四:总结 一: 设想 简单解释下上图就是: 首先前端从cookie获取token,如果没有token就跳转到登录页面登录,登录验证之后生成token存在数据库中并返回给前端:前端将这个token保存下来,为了让在浏览器新

  • Vue组件选项props实例详解

    前面的话 组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息.本文将详细介绍Vue组件选项props 静态props 组件实例的作用域是孤立的.这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据.要让子组件使用父组件的数据,需要通过子组件的 props 选项 使用Prop传递数据

  • vue快捷键与基础指令详解

    v-bind可以简写成   : <img src="{{url}}">→<img :src="url" :width="50px"> v-on:click可以写成@click <button @click="up()"></button> v-if实例  可以通过对对象操作条件来实现想要展示的效果 <!DOCTYPE html> <html> <he

  • vue中的scope使用详解

    我们都知道vue slot插槽可以传递任何属性或html元素,但是在调用组件的页面中我们可以使用 template scope="props"来获取插槽上的属性值,获取到的值是一个对象. 注意:scope="它可以取任意字符串"; 上面已经说了 scope获取到的是一个对象,是什么意思呢?我们先来看一个简单的demo就可以明白了~ 如下模板页面: <!DOCTYPE html> <html> <head> <title>

  • 基于Vue的ajax公共方法(详解)

    为了减少代码的冗余,决定抽离出请求ajax的公共方法,供同事们使用. 我使用了ES6语法,编写了这个方法. /** * @param type 请求类型,分为POST/GET * @param url 请求url * @param contentType * @param headers * @param data * @returns {Promise<any>} */ ajaxData: function (type, url, contentType, headers, data) {

  • vue自定义指令directive实例详解

    下面给大家介绍vue自定义指令directive,具体内容如下所示: 官网截图实例 vue除了一些核心的内部定义的指令(v-model,v-if,v-for,v-show)外,vue也允许用户注册自己的一些功能性的指令,有时候你实在是要对Dom操作,这个时候是自定义指令最合适的了. 来直接看例子:当页面加载时使得元素获得焦点(autofocus 在移动版 Safari 是不支持的),就是当页面加载好了,不做任何的操作使得表单自动获得焦点,光标自动在某个表单上代码如下: Vue.directive

  • vue项目中axios使用详解

    axios在项目中(vue)的使用 没有vue项目的使用vue-cli脚手架生成一个webpack模板的项目即可愉快的看下去了~ 如果开发遇到跨域问题可以参考:http://www.jb51.net/article/134571.htm 安装axios到项目中 npm install axios --save 配置wepack别名,不同环境访问不同的配置接口 配置: 使用:import config from 'config' 封装一个axios实例 新建fetch.js,在此创建axios实例

随机推荐