Mock.js 解决什么问题
问题:
前后端分离项目,前端和后端人员都是根据 API 文档进行开发项目的,不应该直接相互依赖, 前端人员不应该等
待后端开发好接口后再进行测试,既然不依赖后端接口,那前端人员应该如何测试呢?
解决:
可以通过模拟数据生成器,通过一定规则 (API文档)生成模拟数据接口, 提供给前端人员进行测试。
安装 Mock.js
为了模拟后台接口提供页面需要的数据,我们引入 Mock.js 为我们提供模拟数据,而不用依赖于后台接口的完成。
安装依赖
执行如下命令,安装依赖包。
# 安装
npm install mockjs
yarn add mockjs --dev
安装完成之后,我们写个例子测试一下。
const Mock = require('mockjs')
const data = Mock.mock({
'items|30': [{
id: '@id',
title: '@sentence(10, 20)',
'status|1': ['published', 'draft', 'deleted'],
author: 'name',
display_time: '@datetime',
pageviews: '@integer(300, 5000)'
}]
})
module.exports = [
{
url: '/vue-admin-template/table/list',
type: 'get',
// 返回响应数据
response: config => {
const items = data.items
return {
code: 20000,
data: {
// 数据条数
total: items.length,
items: items
}
}
}
}
]
const tokens = {
admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
const users = {
'admin-token': {
roles: ['admin'],
introduction: '我是超级管理员',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin'
},
'editor-token': {
roles: ['editor'],
introduction: '我是编辑',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Normal Editor'
}
}
module.exports = [
// 用户登录
{
url: '/vue-admin-template/user/login',
type: 'post',
response: config => {
const { username } = config.body
const token = tokens[username]
// 模拟误差
if (!token) {
return {
code: 60204,
message: 'Account and password are incorrect.'
}
}
return {
code: 20000,
data: token
}
}
},
// 获取用户信息
{
url: '/vue-admin-template/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
const info = users[token]
// 模拟误差
if (!info) {
return {
code: 50008,
message: 'Login failed, unable to get user details.'
}
}
return {
code: 20000,
data: info
}
}
},
// 用户注销
{
url: '/vue-admin-template/user/logout',
type: 'post',
response: _ => {
return {
code: 20000,
data: 'success'
}
}
}
]
在 src 目录下新建一个 mock 目录,创建 mock.js,在里面我们模拟了两个接口,分别拦截用户和菜单的请求,并返回相应的数据。
如下图所示:
修改 Home.vue,在页面放置两个按钮,分别触发用户和菜单的处理请求,成功后弹出获取结果。
浏览器访问:http://localhost:8080/#/,分别点击两个按钮,mock 会根据请求 url 拦截对应请求并返回模拟数据。
获取用户信息
获取菜单信息
什么是 Mock.js
官网:mock官网
文档:mock.js文档
Mock.js 是用于生成随机数据,拦截 Ajax 请求。
通过拦截 Ajax 请求,根据数据模板生成并返回模拟数据,让前端攻城师独立于后端进行开发,帮助编写单元测试。
使用 EasyMock
什么是 EasyMock
Easy Mock 是一个可视化,并且能快速生成模拟数据的服务。是杭州大搜车无线团队出品的一个极其简单、高效、
可视化、并且能快速生成模拟数据的在线 Mock 服务 。
现在 Easy Mock 内置了 Mock.js,我们可以更愉快的伪造数据了。
官网:https://www.easy-mock.com/ 服务器访问不了
文档:https://www.easy-mock.com/docs
梦学谷搭建的Easy Mock: http://mock.mengxuegu.com/
创建项目
-
访问 http://mock.mengxuegu.com/ ,进行登录。
注意:没有单独的注册页面,第一次输入的用户名会自动帮你注册。特别注意没有修改密码的入口,所以一定要记住密码
-
点击右下角 + , 创建一个项目
-
创建一个项目,如下:
创建测试数据接口
-
点击 创建接口
-
EasyMock 添加模拟数据配置
请求地址:/test
请求方式:get
{
"code": 20000,
"message": "操作成功"
}
- 测试数据接口是否正常
调用数据接口
- 在 vue.config.js 文件中使用 devServer.proxy 选项进行代理配置
注意:复制自己创建的 Base URL ,如果要用老师的,就复制源码中的,不要复制文档的。
devServer: {
// 。。省略
before: require('./mock/mock-server.js'),
// 开发环境代理配置
proxy: {
[process.env.VUE_APP_BASE_API] :{ // 是.env.development 文件的'/dev-api':
// 目标服务器地址
target: 'http://mengxuegu.com:7300/mock/5f114e0544ef223bad8c9827/blog-admin',
changeOrigin: true, // 开启代理服务器,
pathRewrite: {
// '^/dev-api': '',
[ '^' + process.env.VUE_APP_BASE_API]: ''
}
}
}
},
- 创建 src/api/test.js 文件,定义调用接口 API
import request from '@/utils/request'
export default{
test() {
return request({
url: '/test',
method: 'get'
})
}
}
- 调用接口获取数据
// 引入 api
import api from '@/api/test'
export default {
//...省略
created() {
this.fetchData()
},
methods: {
fetchData() {
api.test().then(response => {
console.log(response)
})
}
},
}
- 访问 http://localhost:9528/#/dashboard 首页, 查看浏览器是否打印值
Post 请求带参数 报请求超时
修改下 /test 接口请求方式为 post
问题:
Axios 如果发送Post请求,并且带上请求参数时,会一直报请求超时,如下
import request from '@/utils/request'
export default{
test() {
return request({
url: '/test',
method: 'post',
data: {'name': '小二'}
})
}
}
原因:
这个问题是因为mock-server中express的中间件body-parser导致的,表现为不带参数请求没有问题,带上参数就出现那种情况
解决方案是:
- 将 mock\mock-server.js 文件下面的注释掉,再加上新的(大概第12行)
// app[mock.type](mock.url, mock.response)
app[mock.type](mock.url, bodyParser.json(), bodyParser.urlencoded({
extended: true
}), mock.response)
- 然后往下拉,找到下面的注释掉
// app.use(bodyParser.json())
// app.use(bodyParser.urlencoded({
// extended: true
// }))
- 修改后,完整的图示: