详解Vue单元测试case写法


Posted in Javascript onMay 24, 2018

书接上文,karma+webpack搭建vue单元测试环境介绍了vue单元测试环境搭建及查看源文件的测试覆盖覆盖率。今天来说一下vue单元测试思路和case的写法。测试框架使用jasmine,语法参考。

代码地址:https://github.com/MarxJiao/vue-karma-test/tree/spec-demo

测试关注点

对于vue组件,单元测试测试主要关注以下几点:

  1. vue组件加载后,各数据模型是否符合预期
  2. 定义的方法是否可用
  3. filter是否可用
  4. 带有props的组件,数据能否正常传递
  5. 异步更新DOM的情况

组件加载后的状态

要测试组件加载后的状态,首先我们需要将vue组件生成实例。并检测挂载后实例的数据状态。下面是个示例:

我们来看下src/app.vue组件的代码:

<template>
 <div>
  <h1>{{title}}</h1>
  <vc-message :message="message"></vc-message>
 </div>
</template>

<script>
 import child from './components/child.vue'
 export default {
  data() {
   return {
    title: '标题',
    message: '这是子组件'
   }
  },
  components: {
   'vc-message': child
  },
  mounted() {
   this.title = 'Hello world'
  },
  methods: {
   setMessage(msg) {
    this.message = msg;
   }
  }
 }
</script>

组件加载后title的值应该变成'Hello world',所以我们这样来写测试代码

// 引用vue
import Vue from 'vue';

// 引用要测试的组件
import app from '../../src/app.vue';

// 描述要测试的内容
describe('test app.vue', () => {
 
 // 描述要测试的最小单元
 it('组件加载后,title应该是Holle world', () => {

  // 这里将app生成vue实例,并使用 $mount() 模拟挂载状态
  let vm = new Vue(app).$mount();

  // 断言组件的title是否变为了'Hello world'
  expect(vm.title).toEqual('Hello world');
 });
});

执行karma start我们能看到测试通过。

测试组件里面的方法

我们知道vue将data和methods都挂在了vue实例的根节点下,所以测试vue组件中的方法也和上面测试状态一样,直接调用vm的方法就行了。我们来测试以下setMessage方法:

// 引用vue
import Vue from 'vue';

// 引用要测试的组件
import app from '../../src/app.vue';

// 描述要测试的内容
describe('test app.vue', () => {
 
 // 描述要测试的最小单元
 it('设置message为『你好世界』', () => {

  // 这里将app生成vue实例,并使用 $mount() 模拟挂载状态
  let vm = new Vue(app).$mount();

  // 执行setMessage方法
  vm.setMessage('你好世界');

  // 断言组件的message是否变为了'你好世界'
  expect(vm.message).toEqual('你好世界');
 });
});

执行karma start,就会看到测试成功。如果刚才没有关闭karma的话,在watch模式下,测试会自动进行。

怎么样?有没有感觉vue单元测试非常简单,赶紧做起来吧。

filter测试

filter的测试就更简单了。filter就是纯函数,有固定的输入输出,我们只需要执行函数看预期结果就好了。我们为组件添加一个转换大写的filter:

<template>
...

 <h1>{{title | upperCase}}</h1>

...

</template>

<script>

...

 filters: {
  upperCase(str) {
   return str.toUpperCase();
  }
 }

...
</script>

测试这个filter

// 引用要测试的组件
import app from '../../src/app.vue';

// 描述要测试的内容
describe('test app.vue', () => {

 it('upperCase过滤器能把app转换为APP', () => {

  // vue 组件export出来的是个对象,我们直接用这个对象的属性和方发就能调用到要测试的filter
  let appStr = app.filters.upperCase('app');

  // 断言组件的appStr是为'APP'
  expect(appStr).toEqual('APP');
 });
})

props测试

props依赖父组件,这个怎么测试呢。我们来看下vue官方提供的方法

使用Vue.extend()将组件挂载Vue构造器上,用propsData加入props数据,之后new一个Vue实例,这样就生成了一个独立的带props的vm和前面的实例一样,可以进行各种测试。

我们的child组件:

<template>
 <div>
  <div>{{message}}</div>
 </div>
</template>

<script>
 export default {
  props: ['message']
 }
</script>

测试child组件

// 引用vue
import Vue from 'vue';

// 引用要测试的组件
import child from '../../src/components/child.vue';

/**
 * 获取生成的vm
 *
 * @param {Object} Component 组件
 * @param {Object} propsData props数据
 * @return {Object} vue实例
 */
function getRenderedVm (Component, propsData) {
 const Ctor = Vue.extend(Component)
 const vm = new Ctor({ propsData }).$mount()
 return vm
}

// 描述要测试的内容
describe('test child.vue', () => {
 
 // 描述要测试的最小单元
 it('组件加载后,child组件的message应该是「这是子组件」', () => {
  let childvm = getRenderedVm(child, {
   message: '这是message'
  });

  // 断言组件的child组件的props是否生效
  expect(childvm.message).toEqual('这是message');
 });
});

是不是so easy.

异步更新DOM的情况

异步更新DOM的情况,参考vue官网的示例

使用Vue.nextTick来查看异步数据更新后dom是否变化

// 引用vue
import Vue from 'vue';

// 引用要测试的组件
import app from '../../src/app.vue';

// 描述要测试的内容
describe('test app.vue', () => {
 
 // 异步数据更新
 it('数据更新后,视图应该改变', done => {

  // 这里将app生成vue实例,并使用 $mount() 模拟挂载状态
  let vm = new Vue(app).$mount();

  // 挂载后改变title
  vm.title = 'APP';

  Vue.nextTick(() => {
   let title = vm.$el.getElementsByTagName('h1')[0]
   expect(title.textContent).toEqual('APP')
   done();
  })
 });
});

以上就是对vue组件单元测试的用例编写的介绍,例子举得比较简单,主要是介绍各种情况的测试方法。

相关链接

Vue官网单元测试介绍

Jasmine introduction

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

Javascript 相关文章推荐
Javascript 错误处理的几种方法
Jun 13 Javascript
JQuery UI DatePicker中z-index默认为1的解决办法
Sep 28 Javascript
Jquery 例外被抛出且未被接住原因介绍
Sep 04 Javascript
火狐下input焦点无法重复获取问题的解决方法
Jun 16 Javascript
理解Javascript的call、apply
Dec 16 Javascript
利用python分析access日志的方法
Oct 26 Javascript
ES6中module模块化开发实例浅析
Apr 06 Javascript
基于vue-ssr服务端渲染入门详解
Jan 08 Javascript
微信小程序实现通过双向滑动缩放图片大小的方法
Dec 30 Javascript
微信小程序实现点击空白隐藏的方法示例
Aug 13 Javascript
聊聊Vue中provide/inject的应用详解
Nov 10 Javascript
vue+openlayers绘制省市边界线
Dec 24 Vue.js
微信小程序通过保存图片分享到朋友圈功能
May 24 #Javascript
karma+webpack搭建vue单元测试环境的方法示例
May 24 #Javascript
react实现点击选中的li高亮的示例代码
May 24 #Javascript
浅谈Webpack 是如何加载模块的
May 24 #Javascript
jquery.onoff实现简单的开关按钮功能(推荐)
May 24 #jQuery
详解javascript中的变量提升和函数提升
May 24 #Javascript
JavaScript轮播停留效果的实现思路
May 24 #Javascript
You might like
PHP伪造referer实例代码
2008/09/20 PHP
PHP编程最快明白(第一讲 软件环境和准备工作)
2010/10/25 PHP
重新封装zend_soap实现http连接安全认证的php代码
2011/01/12 PHP
PHP学习笔记之三 数据库基本操作
2011/01/17 PHP
simplehtmldom Doc api帮助文档
2012/03/26 PHP
通过PHP的内置函数,通过DES算法对数据加密和解密
2012/06/21 PHP
php自定义扩展名获取函数示例
2016/12/12 PHP
PHP实现一个多功能购物网站的案例
2017/09/13 PHP
JS 建立对象的方法
2007/04/21 Javascript
Extjs Ajax 乱码问题解决方案
2009/04/15 Javascript
javascript通过class来获取元素实现代码
2013/02/20 Javascript
JS中的substring和substr函数的区别说明
2013/05/07 Javascript
浅谈Javascript中匀速运动的停止条件
2014/12/19 Javascript
JavaScript通过setTimeout实时显示当前时间的方法
2015/04/16 Javascript
理解JavaScript中worker事件api
2015/12/25 Javascript
浅析Bootstrap表格的使用
2016/06/23 Javascript
原生js图片轮播效果实现代码
2016/10/19 Javascript
jquery心形点赞关注效果的简单实现
2016/11/14 Javascript
mui开发中获取单选按钮、复选框的值(实例讲解)
2017/07/24 Javascript
jquery应用实例分享_实现手风琴特效
2018/02/01 jQuery
解决mui框架中switch开关通过js控制开或者关状态时小圆点不动的问题
2019/09/03 Javascript
详解Webpack抽离第三方类库以及common解决方案
2020/03/30 Javascript
python八大排序算法速度实例对比
2017/12/06 Python
Python使用pyautogui模块实现自动化鼠标和键盘操作示例
2018/09/04 Python
Python使用random.shuffle()打乱列表顺序的方法
2018/11/08 Python
基于wxPython的GUI实现输入对话框(1)
2019/02/27 Python
vscode 配置 python3开发环境的方法
2019/09/19 Python
浅谈Python中range与Numpy中arange的比较
2020/03/11 Python
python爬虫beautifulsoup库使用操作教程全解(python爬虫基础入门)
2021/02/19 Python
html5 Canvas画图教程(7)—canvas里画曲线之quadraticCurveTo方法
2013/01/09 HTML / CSS
Larsson & Jennings官网:现代瑞士钟表匠
2018/03/20 全球购物
党风廉政建设责任书
2014/04/14 职场文书
银行先进个人事迹材料
2014/05/11 职场文书
党员教师一句话承诺
2014/05/30 职场文书
2015重阳节敬老活动总结
2015/07/29 职场文书
关于食品安全的演讲稿范文(三篇)
2019/10/21 职场文书