结合数据生成工具
本章将会教你如何结合数据生成工具来封装自定义装饰器,让你的代码更加简洁而优雅,并结合数据生成工具完成业务mock。
准备项目结构
bash
project
├── api
│ ├── common
│ │ └── index.ts # 通用接口装饰器
│ └── userApi.ts # 真实接口类
└── mock
├── common
│ └── index.ts # 通用方法
├── models
│ └── userModel.ts # 定义数据模型
└── userMock.ts # 封装用户mock装饰器定义数据模型
这里数据模型通过data-faker-plus来定义,在/mock/models/userModel.ts
ts
import { DataField, DataModel, defineModel, faker } from 'data-faker-plus';
// 定义用户数据模型
@DataModel('user')
export class UserModel {
@DataField('string.uuid')
declare id: string;
@DataField('person.firstName')
declare firstName: string;
@DataField('person.lastName')
declare lastName: string;
@DataField(['number.int', { min: 1, max: 120 }])
declare age: number;
@DataField(ctx => {
return faker.internet.email({ firstName: ctx.firstName, lastName: ctx.lastName });
})
declare email: string;
@DataField('phone.number')
declare phone: string;
@DataField('person.sex')
declare sex: string;
}封装 mock 装饰器
定义通用方法
/mock/common/index.ts,在这里面定义了通用错误处理方法
ts
/**
* 公共方法
*/
import { HttpResponse } from 'msw';
/**
* 网络错误
* @returns
*/
export function netWorkError() {
return HttpResponse.error();
}定义用户 mock 装饰器
/mock/userMock.ts,在这里面定义了用户相关的mock装饰器
ts
import { HttpResponse, Mock, MockHandlers } from '@/index';
import { fakeData, useModel } from 'data-faker-plus';
import { UserModel } from './models/userModel';
import { netWorkError } from './common';
// 使用data-faker-plus生成假数据
const users = fakeData(useModel(UserModel), 30);
/**
* 模拟用户页面
*/
export function MockUserPages() {
let handlers = {
default: () => {
return HttpResponse.json({
message: 'success',
data: users,
});
},
error: netWorkError,
};
return Mock(handlers);
}
/**
* 模拟删除用户
*/
export function MockUserDelete() {
let handlers: MockHandlers = {
default: ({ params }) => {
// 获取用户参数
const { id } = params;
// 找到用户
const user = users.find((item: any) => item.id === id);
// 删除用户
users.splice(users.indexOf(user), 1);
// 返回成功信息
return HttpResponse.json({
message: 'delete success',
});
},
error: netWorkError,
};
return Mock(handlers);
}
/**
* 模拟更新用户
*/
export function MockUserUpdate() {
// 成功时的方法
const success: MockHandlers = async ({ request }) => {
// 获取请求体参数
let user = await request.json();
user = JSON.parse(JSON.stringify(user)) as UserModel;
if (!user || !user.id) {
return HttpResponse.json({
status: 400,
message: 'params error',
});
}
// 更新用户信息
const index = users.findIndex((item: any) => item.id === user.id);
users[index] = user;
return HttpResponse.json({
message: 'update success',
});
};
// 失败时的方法
const error = netWorkError;
// 返回 Mock 装饰器
return Mock({
default: success,
error,
});
}
/**
* 添加用户
*/
export function MockUserCreate() {
// 成功时的方法
const success: MockHandlers = async ({ request }) => {
// 获取请求体参数
let user = await request.json();
// 新增用户
users.unshift(user);
return HttpResponse.json({
message: 'create success',
});
};
// 失败时的方法
const error = netWorkError;
// 返回 Mock 装饰器
return Mock({
default: success,
error,
});
}封装接口装饰器
/api/common/index.ts
ts
import { HttpMethodDecoratorConfig, Post } from '@/index';
/**
* 分页查询装饰器
* @param config 请求配置
* @returns post装饰器
*/
export function Pages(config: HttpMethodDecoratorConfig) {
config.headers = {
'Content-Type': 'application/json',
};
return Post(config);
}定义真实接口类
/api/userApi.ts
ts
import { Delete, Get, Post, Put } from '@/core/httpMethod';
import { HttpApi } from '@/core/ioc';
import { Pages } from './common';
import { BodyParam, PathParam } from '@/core/params';
import { MockUserCreate, MockUserDelete, MockUserPages, MockUserUpdate } from '../mock/userMock';
@HttpApi({
baseURL: 'http://localhost:3000/api/users',
mock: {
on: true,
condition: () => {
return process.env.NODE_ENV === 'test';
},
},
})
class UserApi {
/**
* 用户分页查询接口
* @param page 页号
* @param size 每页数量
*/
@Pages({ url: '/pages/:page/:size' })
@MockUserPages()
getUserPages(@PathParam('page') page: number, @PathParam('size') size: number): any {}
/**
* 删除用户接口
* @param id 用户ID
*/
@Delete('/:id')
@MockUserDelete()
deleteUser(@PathParam('id') id: number): any {}
/**
* 添加用户接口
*/
@Post('/')
@MockUserCreate()
addUser(@BodyParam() user: { name: string; age: number }): any {}
/**
* 更新用户接口
*/
@Put('/')
@MockUserUpdate()
updateUser(@BodyParam() user: { id: number; name: string; age: number }): any {}
}
export const userApi = new UserApi();调用接口测试
打开mock开关,测试接口是否正常工作
ts
// 一定要先开启mock开关
MockAPI.on();
const { data } = await userApi.getUserPages(1, 10)();
console.log(data);
// 删除用户
const { data: data2 } = await userApi.deleteUser(1)();
console.log(data2);
// 新增用户
const { data: data3 } = await userApi.addUser({ name: 'test', age: 18 })();
console.log(data3);