一、jest实战之常见断言API
toBe 匹配器类似于object.is或者===,精确相等
test("测试toBe", () => {
// toBe为匹配器 matchers
// toBe相当于js中的 object.is ===
expect(10).toBe(10); // true
});
test("测试toBe", () => {
const person = { name: "zhangsan" };
expect(person).toBe({ name: "zhangsan" }); // false,因为两个对象的地址是不一样的
});
toEqual 测试对象的内容是否相等,不比较对象的地址,只关心对象的内容是否一致,递归检查对象或数组的每个字段
test("测试toEqual", () => {
const person = { name: "zhangsan" };
expect(person).toEqual({ name: "zhangsan" }); // true
});
toBeNull 测试某个变量是否为null,如果是则true,否则false
test("测试toBeNull", () => {
const a = null;
expect(a).toBeNull(); // true
});
toBeUndefined 和 toBeDefined 测试某个变量是否未定义,如果是则true,否则false
test('测试toBeUndefined', () => {
const a = undefined;
expect(a).toBeUndefined(); // true
});
test('测试toBeUndefined', () => {
const a = '';
expect(a).toBeUndefined(); // false
});
test('测试toBeUndefined', () => {
const a = null;
expect(a).toBeUndefined(); // false
});
test('测试toBeDefined', () => {
const a = null;
expect(a).toBeDefined(); // true
});
test('测试toBeDefined', () => {
const a = undefined;
expect(a).toBeDefined(); // false
});
toBeTruthy 测试某个变量是否为真,如果是则true,否则false
test('测试toBeTruthy', () => {
const a = undefined;
expect(a).toBeTruthy(); // undefined 视为false
});
test('测试toBeTruthy', () => {
const a = null;
expect(a).toBeTruthy(); // null视为false
});
test('测试toBeTruthy', () => {
const a = 0;
expect(a).toBeTruthy(); // 0 视为false
});
test('测试toBeTruthy', () => {
const a = 1;
expect(a).toBeTruthy(); // 1 视为true
});
toBeFalsy 测试某个变量是否为假,如果是则true,否则false
test('测试toBeFalsy', () => {
const a = 1;
expect(a).toBeFalsy(); // false,因为1 视为true
});
test('测试toBeFalsy', () => {
const a = undefined;
expect(a).toBeFalsy(); // true,因为undefined 视为false
});
test('测试toBeFalsy', () => {
const a = null;
expect(a).toBeFalsy(); // true,因为null 视为false
});
test('测试toBeFalsy', () => {
const a = 0;
expect(a).toBeFalsy(); // true,因为0 视为false
});
test('测试toBeFalsy', () => {
const a = 0;
expect(a).not.toBeFalsy(); // false,因为0 视为false,但是匹配器要的是真
});
数字相关
test('测试toBeGreaterThan', () => {
const count = 10;
expect(count).toBeGreaterThan(9); // true,表示希望count这个变量的值比9大
});
test('测试toBeLessThan', () => {
const count = 10;
expect(count).toBeLessThan(9); // false,表示希望count这个变量的值比9小
});
test('测试toBeGreaterThanOrEqual', () => {
const count = 9;
expect(count).toBeGreaterThanOrEqual(9); // true,表示希望count这个变量的值大于等于9
});
test('测试toBeLessThanOrEqual', () => {
const count = 9;
expect(count).toBeLessThanOrEqual(9); // true,表示希望count这个变量的值小于等于9
});
test('测试toBeCloseTo', () => {
const firstNumber = 0.1;
const secondNumber = 0.2;
expect(firstNumber + secondNumber).toEqual(0.3); // 结果是false,因为js计算浮点数的时
expect(value).toBe(0.3); // 这句会报错,因为浮点数有舍入误差候,有可能会溢出或者说不准确,这种情况下最好用toBeCloseTo
});
test('测试toBeCloseTo', () => {
const firstNumber = 0.3;
const secondNumber = 0.4;
expect(firstNumber + secondNumber).toBeCloseTo(0.7); // true
});
字符串相关
test('测试toMatch', () => {
const str = 'www.baidu.com';
expect(str).toMatch('baidu'); // true, 表示str字符串中是否包含baidu这个字符串
expect(str).toMatch(/baidu/); //true,这里还可以写正则表达式
});
数组相关
test('测试toContain', () => {
const arr = ['dee', 'lee'];
expect(arr).toContain('dee'); // true, 表示arr数组中是否包含dee这个字符串元素
});
test('测试toContain', () => {
const arr = ['dee', 'lee'];
const data = new Set(arr);
expect(data).toContain('dee'); // true, 表示arr数组中是否包含dee这个字符串元素
});
异常情况
const throwNewErrorFunc = () => {
throw new Error('this is a new error');
}
test('测试toThrow', () => {
expect(throwNewErrorFunc).toThrow(); // true, 表示希望throwNewErrorFunc这个方法运行的时候能够抛出一个异常
});
test('测试toThrow', () => {
expect(throwNewErrorFunc).not.toThrow(); // false, 表示希望throwNewErrorFunc这个方法运行的时候不能够抛出异常
});
test('测试toThrow', () => {
expect(throwNewErrorFunc).toThrow('this is a new error'); // true, 表示希望throwNewErrorFunc这个方法运行的时候能够抛出一个异常,并且内容是'this is a new error'
expect(throwNewErrorFunc).toThrow(/this is a new error/); // 也可以是正则表达式
});
二、jest实战之vue组件
本文以navbar组件来举例说明,效果如下
组件代码如下
<template>
<div class="nav-container">
<div @click="itemAction(index)" class="nav-item" :class="{ selected: selectIndex == index }"
:style="{ width: itemWidth }" v-for="(item, index) in navArr" :key="index">
<p class="nav-title">{{ formatTitle(item.title) }}</p>
</div>
</div>
</template>
<script>
export default {
name: "Navbar"
};
</script>
<script setup>
import { computed, defineEmits } from 'vue';
const props = defineProps({
navArr: {
type: Array,
default: [
{
title: '菜单1'
}, {
title: '菜单2'
}, {
title: '菜单3'
}, {
title: '菜单4'
}
]
},
selectIndex: {
type: Number,
default: 0
}
})
const itemWidth = computed(() => {
return (100 / props.navArr.length) + '%';
})
const emit = defineEmits(['itemTap'])
const itemAction = (index) => {
emit('itemTap', index);
}
const formatTitle = (title) => {
return title + '美女';
}
</script>
<style lang="scss" scoped>
.nav-container {
display: flex;
width: 100%;
.nav-item {
display: flex;
justify-content: center;
align-items: center;
padding: 10px 0;
cursor: pointer;
}
.selected {
color: red;
}
}
</style>
1、jest实战之vue组件props渲染
测试目标:给定任意符合规则的navArr数组,测试每一项的title是否为给定数组的title+美女
import { shallowMount } from "@vue/test-utils";
import Navbar from "@/components/navbar.vue";
describe("navbar组件测试", () => {
test("测试props渲染", () => {
let navArr = [
{
title: "发糕",
},
{
title: "北京烤鸭",
},
{
title: "天津麻花",
},
];
const wrapper = shallowMount(Navbar, {
props: {
navArr: navArr,
},
});
const options = wrapper.element.querySelectorAll(".nav-item");
const result = Array.prototype.every.call(options, (option, index) => {
const text = option.querySelector("p").textContent;
return text === navArr[index].title + "美女";
});
expect(result).toBe(true);
});
});
测试结果:passed
2、jest实战之vue组件class动态渲染
测试目标:给定任意符合规则的selectIndex下标,测试下标为selectIndex的元素的class是否为nav-item selected
import { shallowMount } from "@vue/test-utils";
import Navbar from "@/components/navbar.vue";
describe("navbar组件测试", () => {
test("测试class动态渲染", () => {
const selectIndex = 2;
const wrapper = shallowMount(Navbar, {
props: {
selectIndex: selectIndex,
},
});
const elements = wrapper.element.querySelectorAll(".nav-item");
let result = false;
let className = elements[selectIndex].getAttribute("class");
if (className == "nav-item selected") {
result = true;
}
expect(result).toBe(true);
});
});
测试结果:passed
3、jest实战之vue组件method方法
测试目标:给定任意符合规则的字符串,测试方法返回的是否为字符串+美女
import { shallowMount } from "@vue/test-utils";
import Navbar from "@/components/navbar.vue";
describe("navbar组件测试", () => {
test("测试method方法", () => {
const wrapper = shallowMount(Navbar);
expect(wrapper.vm.formatTitle('李白')).toBe('李白美女');
});
});
测试结果:passed
写在最后
如果你还不会在vue3项目中配置jest,推荐浏览作者的上一篇文章Vue3项目实践jest,学会了升职加薪(上篇)
推荐两个作者参与的开源项目,如果项目有帮助到你,欢迎star
一个简单的基于Vue3、TS、Vite、qiankun技术栈的后台管理项目:www.xkxk.tech
一个基于Vue3的仿Element plus组件项目:ui.xkxk.tech