vue中使用jest单元测试

前言

当我初次听到单元测试时,心里的第一感觉就两个字nb,然后就是疑惑,这是啥,干啥用,对代码又有什么帮助?接下来我会细细说一说我在学习以及应用单元测试的一些心得。(安装教程不再叙述,按照文档教程自行学习)

文档推荐

学习新知识,有中文文档当然是最好的啦!
Vue Test Utils
jest中文文档

组件挂载相关方法

  • shallowMount
    shallowMount:
        创建一个包含被挂载和渲染的 Vue 组件的 Wrapper。与之对应的还有一个mount。
    shallowMount与mount的区别:
        在文档中描述为"不同的是被存根的子组件",大白话就是shallowMount不会加载子组件,不会被子组件的行为属性影响该组件。
    为什么使用shallowMount而不使用mount:
        我认为单元测试的重点在"单元"二字,而不是"测试",想测试子组件再为子组件写对应的测试代码即可。
import { shallowMount } from '@vue/test-utils'
import Foo from './Foo.vue'

describe('Foo', () => {
    const wrapper = shallowMount(Foo)
})
  • Wrapper(这里只记录一些我经常使用的)
    Wrapper:
        Wrapper 是一个包括了一个挂载组件或 vnode,以及测试该组件或 vnode 的方法。
    Wrapper.vm:
        这是该 Vue 实例。你可以通过 wrapper.vm 访问一个实例所有的方法和属性。
    Wrapper.classes:
        返回是否拥有该class的dom或者类名数组。
    Wrapper.find:
        返回第一个满足条件的dom。
    Wrapper.findAll:
        返回所有满足条件的dom。
    Wrapper.html:
        返回html字符串。
    Wrapper.text:
        返回内容字符串。
    Wrapper.setData:
        设置该组件的初始data数据。
    Wrapper.setProps:
        设置该组件的初始props数据。
    Wrapper.trigger:
        用来触发事件。
<template>
	<div class="jest">
		<div class="name">{{name}}</div>
		<div class="name">{{name}}{{text}}</div>
		<div class="text" @click="add">{{text}}</div>
	</div>
</template>
<script src="./script.js">
export default {
	name:"Foo",
	props:{
		name:{
			type: String,
			default: '王大大'
		}
	},
    data() {
        return {
            text: 123
        }
    },
    methods:{
    	add(){
			this.text += 1
		}
    }
}
</script>
import { shallowMount } from '@vue/test-utils'
import Foo from './Foo.vue'

describe('Foo', () => {
    const wrapper = shallowMount(Foo)
    console.log(Wrapper.classes())	//['jest','name','test']
    console.log(Wrapper.classes('jest'))	//true
    console.log(Wrapper.find('name').text())	//返回第一个class是name的dom的内容   王大大
    console.log(Wrapper.findAll('name'))	//返回dom数组
    console.log(Wrapper.findAll('name').at(0))	//取dom数组中的第一个
    Wrapper.setData({text : 1})
    console.log(Wrapper.vm.text)	//1
    Wrapper.setProps({name : "李大大"})
    console.log(Wrapper.vm.name)	//李大大
    Wrapper.find('text').trigger("click")
    console.log(Wrapper.vm.text) // 2
})
  • 挂载选项
    就是shallowMount或者mount的时候可以设置一些初始化内容。具体可以初始化的全部内容请查询文章开始的文档。
import { shallowMount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = shallowMount(Foo, {
	data() {
		return {
			bar: 'my-override'
		}
  },
  propsData: {
		msg: 'aBC'
  }
  mocks: {
        $route: {
            query: {
                aaa: '1',
            }
        },
        $router: {
            push: jest.fn(),
            replace: jest.fn(),
        }
    }
})

jest-api

  • 匹配器
    使用不同匹配器可以测试输入输出的值是否符合预期。
    toBe:判断是否相等
    toBeNull:判断是否为null
    toBeUndefined:判断是否为undefined
    toBeDefined:与上相反
    toBeNaN:判断是否为NaN
    toBeTruthy:判断是否为true
    toBeFalsy:判断是否为false
    toContain:数组用,检测是否包含
    toHaveLength:数组用,检测数组长度
    toEqual:对象用,检测是否相等
    toThrow:异常匹配(没用过)
describe('Foo', () => {
	expect(2 + 2).toBe(4)
	expect(null).toBeNull()
	expect(undefined).toBeUndefined()
	let a = 1;
	expect(a).toBeDefined()
	a = 'ada';
	expect(a).toBeNaN()
	a = true;
	expect(a).toBeTruthy()
	a = false;
	expect(a).toBeFalsy()
	a  = [1,2,3];
	expect(a).toContain(2)
	expect(a).toHaveLength(3)
	a = {a:1};
	expect(a).toEqual({a:1})
})
  • mock函数
    例如:在一个vue组件中,ajax请求、路由跳转是常常用到的,但是在单测代码中,我们并不能正确的知道他是否执行并达到了预期的效果,这时就需要mock函数。在上文挂载选项中的mocks.$router就是一种mock函数的应用实例。
    mock函数自然是要使用该函数,下面是一些函数的常用匹配器
    toBeCalledTimes:判断函数被执行的次数
    toBeCalled:判断函数是否被执行
<template>
	<div class="jest" @click="go"></div>
</template>
<script src="./script.js">
export default {
	name:"Foo",
    methods:{
    	go(){
			this.$router.push({path:"/a"})
		}
    }
}
</script>
import { shallowMount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = shallowMount(Foo, {
  mocks: {
        $router: {
            push: jest.fn(),
            replace: jest.fn(),
        }
    }
})

wrapper.find(“jest").trigger("click");
expect(wrapper.vm.$router.push).toBeCalled();
wrapper.find(“jest").trigger("click");
expect(wrapper.vm.$router.push).toBeCalledTimes(2);

promise模拟

jest.mock('@root/api'); //模拟api请求函数
import {getList} from '@root/api';
const listJson = JSON.parse(require('fs').readFileSync('./mock/getList.json')); //引入mock好的json数据
getList.mockResolvedValue(Promise.resolve(listJson)); //模拟promise返回
getList().then(res => {
	expect(res).toEqual(listJson);
})

为什么要使用单测

说了这么多,那为什么要使用单测呢。在看完上面的描述我想大家也是一头郁闷,单测有用吗?答案当然是有。下面举个例子:

<template>
	<div class="jest"></div>
</template>
<script src="./script.js">
import {getList} from '@root/api';
export default {
	name:"Foo",
    created(){
    	getList()
    	.then(res => {
    		this.initData(res)
    	})
    },
    methods:{
		initData(data){
			data.name = '王大大';
		}
	}
}
</script>
import { shallowMount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = shallowMount(Foo)

这时候就会报错data.name,因为data不一定有值。正确案例如下

<template>
	<div class="jest"></div>
</template>
<script src="./script.js">
import {getList} from '@root/api';
export default {
	name:"Foo",
    created(){
    	getList()
    	.then(res => {
    		this.initData(res)
    	})
    },
    methods:{
		initData(data = {}){
			data.name = '王大大';
		}
	}
}
</script>

说白了就是让你的代码逻辑更符合预期结果。

总结

目前在vue中用到的一些基本知识都已经总结完了,如果以后在工作中使用了新的api,时间充裕的情况下我会持续更新哦~
一起加油吧少年,对了,最后说一句和文章无关的话–“娶妻娶贤,纳妾纳色”
别多想,就是最近听到比较记忆犹新的一句。

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风舞红枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值