1. vue-cli 创建一个demo
- 创建一个 demo
vue create demo
- 在VUE-CLI 是有提供测试插件的,所以在构建项目时选择一个测试框架。
- 运行测试脚本
在package.json 中可以看到运行测试脚本命令
npm run test:unit
执行后可以看到对 HelloWord组件 测试通过
2. 单测流程
一般我们写的单元测试是针对组件或是方法。
- 方法
- 在src 下创建一个 utils文件并创建addition.js
// addition.js
export const addition = (a, b) => {
return a + b;
}
- 在test/unit下创建一个测试文件:test-add.spec.js
// 由于Mocha测试框架没有断言库,所以需要引入 chai 来做断言
import { expect } from "chai";
// 引入需要测试方法
import {addition} from "@/utils/addition";
it("加法函数测试", () => {
expect(addition(1, 2)).to.be.equal(3);
});
it 代表一条测试样例
'expect(addition(1, 2)).to.be.equal(3);' 这条语句可以理解为 期望 addition(1, 2) 执行结果等于 3.
- 执行下测试命令,可以看到测试通过
- 组件
- 在components下创建测试用的Counter组件
组件功能是点击按钮,之后调用 increment 方法,使得count+1,且count计数在偶数会显示、奇数会隐藏
<template>
<div>
<span v-show="showCount" id="count">{{count}}</span>
<button @click="increment"></button>
</div>
</template>
<script>
export default {
name: 'Counter',
data() {
return {
count: 1,
};
},
computed: {
showCount() {
return this.count%2 === 0;
}
},
methods: {
increment() {
this.count++;
}
},
}
</script>
- 在tests/unit 下创建对Counter组件的测试文件
import { expect } from "chai";
import Vue from "vue";
import { mount } from "@vue/test-utils";
import Counter from "@/components/Counter.vue";
describe("测试计数器", () => {
it("count内容", () => {
const Constructor = Vue.extend(Counter);
const vm = new Constructor().$mount();
expect(vm.$el.querySelector("span").innerHTML).to.be.equal("1");
});
it("点击按钮", async () => {
const wrapper = mount(Counter);
await wrapper.find("button").trigger("click");
expect(wrapper.find("#count").text()).to.be.equal("2");
});
});
describe("测试span是否存在", () => {
const wrapper = mount(Counter);
it("点击按钮span显示", async () => {
expect(wrapper.find("span").isVisible()).to.be.equal(false);
await wrapper.find("button").trigger("click");
expect(wrapper.find("span").isVisible()).to.be.equal(true);
});
});
describe (...); 代表一个测试集
通常获取一个vue实例通过 Vue.expend(xxx) 创建一个构造器construct,再new一个实例并调用 mount('xxx') 将其挂在到某一节点上。上例可以理解未创建一个Counter实例并挂在到内存中。
vue 为了方便测试提供了一些测试工具,比如上例所示的 mount 就方便我们创建一个实例,trigger 方便我们触发一个dom节点上的事件(这里模拟触发点击事件)等
更多的工具可以参考官方文档:https://vue-test-utils.vuejs.org/zh/api/wrapper/#%E5%B1%9E%E6%80%A7
- 运行测试文件
这里可以看到会将 tests/unit 下的所有测试文件都执行(可以看到之前的加法函数也进行了测试)。
如果我们只想测试某一文件,可以通过如下命令实现:npm run test:unit -r 测试文件路径
3. Mock数据流程
我理解的mock作用是为了前端开发时可以根据开发前与后端确定的接口文档,在本地服务器生产一些数据,本来需要从服务器获取的数据由本地Mock给出。这样前端在开发时不会因为后端接口未上线而阻塞,且后端完成开发后只需要更改请求路径就可以打通整体流程,有利于提升开发效率。
- 安装所需npm包
npm install axios --save
npm install mockjs --save-dev
npm install json5 --save-dev
axios: 用于发送http请求
mockjs:用于模拟一些mock数据
json5: 是对json的拓展,编写方式类似于js的对象,允许添加注释便于编写
- axios发送get请求
import axios from 'axios';
export default {
name: 'HelloWorld',
props: {
msg: String
},
mounted() {
axios.get('/user/infos')
.then(data => console.log(data))
.catch(err => console.error(err))
}
}
上例是在初始化项目的HelloWorld.vue 组件中添加get请求
- 创建mock数据
在根目录下创建mock/index.js
const fs = require("fs");
const path = require("path");
const Mock = require("mockjs");
const JSON5 = require("json5");
function getJsonFile(filePath) {
var json = fs.readFileSync(path.resolve(__dirname, filePath), "utf8");
return JSON5.parse(json);
}
module.exports = function(app) {
app.get("/user/infos", function(req, res) {
var json = getJsonFile("./send.json5");
res.json(Mock.mock(json));
});
};
send.json5
{
id: '@id()',
username: '@cname()',
}
- 拦截http请求,通过通过本地服务器发送mock数据
这里拦截是通过webpack中devServe.before这个中间件,先于服务器去处理发送的网络请求
在根目录下创建 vue.config.js
module.exports = {
devServer: {
before: require('./mock/index.js')
},
};
相关文档:https://webpack.js.org/configuration/dev-server/#devserverbefore
启动运行demo,可以看到获取到了mock的数据