一晃又是好几个月没有更新文章了,这人真的是懒起来就没啥下限,好几次都准备开始写了,但又最后注意力分散到其他事情上面了,反复告诫自己几次后,也是趁着最近也到了春节长假,准备开始好好写点东西,今天要说的内容是,对于一个原生开发来讲,平时开发中经历的最多的就是去展示点数据,或者完成几个页面交互,大多数此类需求都会从后端接口中读取点配置或者字段来完成,此时如果有现成的接口的话那么这种需求很快就能完成,但是如果万一没有这种接口,后端也在同步开发中,那么我们如何来调试自己的页面呢?数据从哪来呢?此时资深牛马们都知道,遇到这种问题咱就去mock数据,至于如何mock,工作了那么多年也见过好几种,大致的列了一下,可以看看有没有你熟悉的在里面
方法 | 优点 | 缺点 |
---|---|---|
直接在代码中写假数据,完事以后删掉 | 简便,适用于任何人 | 数据无法复用,用完必须立马删除,对于Android或者iOS开发来讲,每次更改数据还需要花很长一段时间去编译,影响效率 |
在项目中写mock数据的配置文件,在对应接口处读取该配置文件拿数据 | 数据可复用 | 需要增加额外读取文件代码,用完必须立马删除 |
使用抓包工具配置mock文件 | 零代码变动,安全 | 需要本地维护大量mock文件 |
使用ktor-server | 可以弥补上述三种方法的所有缺点 | 需要一定kotlin基础,数据需要配置对应的data class |
乍一看怎么都有缺点呢,到底怎么样才能找到一种完全适合自己的mock数据的方法呢?最直接的方法就是再搭一个服务器,当然这次不是用ktor-server了,而是用Nestjs
Nestjs介绍,安装以及初始化项目
根据官网介绍,Nestjs是一个可搭建具有高效的,可依赖可扩展的Nodejs服务端应用框架,使用渐进式JavaScript同时也支持TypeScript,安装Nestjs很简单,运行以下命令即可
npm i -g @nestjs/cli
安装完了之后使用nest new+项目名称
来初始化自己的项目,比如我们要创建一个名叫coffeenest
的项目,那么就输入以下命令
nest new coffeenest
这个命令后会询问你使用哪一种包管理器,我选择的是npm,回车后生成了一堆样板文件,然后慢慢等待项目初始化
当看到如下提示后,就说明我们这个coffeenest
项目就创建好了
熟悉项目
打开创建好的项目,虽然nest在创建项目的时候创建了不少文件,但是由于我们的目的只是mock数据,所以只需要关注如下几个文件
package.json
package.json
文件中主要是要看一下启动nest服务的脚本命令有哪些,有start
命令也有start:dev
,后者就是多了个监听文件变化的功能,这里我们使用start:dev
将服务启动一下
npm run start:dev
出来如下提示就说明服务启动成功了
如果不信,想要验证下服务是不是真的运行起来了,可以在浏览器中输入localhost:3000,出现如下界面,则证明你的服务的确运行起来了
这个Hello World!就是项目中默认配置的数据,那么如何修改这个数据?又如何配置接口的路径呢?我们看下src底下的文件
main.ts
这个文件是整个项目的入口文件,里面已经有一段默认代码了,不多就几行
从这几行代码中我们可以得到如下信息
- 项目加载的是
AppModule
模块 - 如果没有额外配置env端口,那么项目使用默认端口号3000
app.modules.ts
AppModule
的代码在app.modules.ts
里面,这是应用的根模块,可以看到里面也都是一些配置类的代码,分别配置了AppModule
这个模块的所有service层与controller层的模块
app.service.ts
这个文件用来配置当前service可以提供的数据,可以看到我们之前看到的Hello world!就是在这个文件里面的getHello()
函数返回的
可以尝试更改下getHello()
函数的返回值,可以看到最终运行后得到的结果就是我们更改后的数据
app.controller.ts
知道如何更改数据之后,再来看看如何配置访问数据的接口路径,现在访问的路径是根目录,造成这个的原因可以看app.controller.ts
的代码
有两个装饰器,@Controller
装饰在了类AppController
上,我们控制器Controller一定要有@Controller
来装饰,也可以给控制器添加前缀,起到分组的作用
添加了前缀之后,我们如果现在再去访问localhost:3000的话,就不会有返回值了,显示的是404
现在正确的路径是在原本的路径后面添加上我们增加的coffee
前缀,这样才能获得数据
同样的,getHello()
方法现在没有配置任何路径,如果在getHello()
的@Get
装饰器上加上路径参数,那么获取数据的路径也变了
到了这里,我们就大致的清楚如何给接口配置mock数据了,控制器的前缀加上方法的路径,就等于你要mock接口的实际路径,至于数据部分就在service里面配置,下面来看看如何处理数据部分
造数据
其实吧,这个部分也可以省略,毕竟大多数场景下数据无非就是一串json,这种东西无论是从接口文档的示例代码中,还是用抓包工具抓取现成的数据都可以拿到,比如现在我们想要配置一段订单列表的数据,大致的样子如下所示
这段数据看起来没啥问题,也可以满足我们展示数据调试页面的目的,但是这里面也隐藏着一些不足之处,比如
- 数组大小不可变,每当要改变数组大小时候,这个时候需要对数组的长度做一次更改
- 文案无法调试临界值场景,一般我们的文案都会放在一个TextView里面,有时候我们会测试过长的文案会不会在TextView里面显示异常,这个时候需要对数据的文案做一次修改
- 订单状态字段type如果有多种类型,如果我们想要查看其他类型在页面上的展示效果,就需要对type字段做修改
现在我们发现了,在这么一段简单的数据中,存在着这么些地方需要我们反复对代码做修改,这还是我随便写出来的一段json数据,正常情况下实际数据还要复杂,所面临的问题更多,这对于正处在研发阶段的我们来讲,可能并没有太多的时间去完善这些数据,这种情况,就需要寻找其他方法来帮我们解决,下面一起来了解下Mockjs
Mockjs
它有哪些优势呢?
- 前后端分离:让前端工程师独立于后端开发
- 开发无侵入:不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据
- 数据类型丰富:支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等
- 增加单元测试的真实性:通过随机数据,模拟各种场景
- 用法简单:符合直接的接口
- 方便扩展:支持支持扩展更多数据类型,支持自定义函数和正则
使用以下方式来安装Mockjs
npm install mockjs
如果用的是TypeScript,那么还需要安装以下插件
npm i --save-dev @types/mockjs
导入Mock库
import Mock from 'mockjs'
这样我们刚才的数据就可以使用Mockjs来生成了
这里虽然数组里面现在只有一个元素,但是由于字段orderList
后面已经加了一段2-10的描述,所以这段代码代表的意思就是会随机生成一个数组,大小在2-10之间
介于这种特性,在某些数组中存在子数组的情况,我们就不需要一一把所有数组以及其元素列出来了,只需要使用如下这种方式就可以快速完成
又比如之前说的如果我们想测试某个文案的临界值情况,就不需要专门给某个字段设置一段文案,可以使用@cword(min,max)
来表示min表示该文案最短长度,max表示该文案最大长度,@cword
表示是一段中文,这样Mockjs会随机帮我们生成一段大小在min与max之间的中文文案
productName
现在可以随机生成一个长度在3到15之间的中文文案,注意的是如果将@cword
改成@word
,那么代表的意思就是一串英文字母文案,上图中的description
就是使用@word(2,8)
生成的,像这样的语法Mockjs还有很多,下面列举几个常用的
@id
这个表示生成一串有唯一性的数字字符
@integer
表示生成一个随机的整型数,后面可以添加取值范围,意思是随机生成一个在给定范围内的一个整型数值,例如@integer(10,100)
那就是随机生成一个在10到100之间的一个整型数
那么如果我们想生成一段连续的整数,该怎么做呢?可以使用如下写法
可以在字段的后面加上+1,值设置为连续整数的初始值,这样就获得了一串连续的整数
@bool或者@boolean
生成布尔值可以使用这两种写法
@Date
用来生成随机日期,默认格式为yyyy-MM-dd
当然也可以自定义格式,也可以把时分秒也展示出来
@color
随机生成一个十六进制的色值
@name
生成随机的英文名
@cname
生成随机的中文名
@image
在对于有图片场景的情况,Mockjs也提供了随机生成图片链接的方式,使用@image
可以随机生成一张任意大小的图片
随意找一个链接打开,可以看到图片是这样的
@image
还支持自定义背景颜色以及文字颜色和文字内容,使用如下代码生成
第一个参数是图片大小,第二个参数表示背景颜色,第三个参数是文字颜色,第四个参数是文字内容,生成的链接如下所示
新生成的链接长这样
从特定范围内获取一个随机值
这种情况多用在字段为枚举值,取值永远都是那么几个
最后
Mock的方式有很多种,除了文中介绍的几种之外肯定还有其他的,每个人都有自己用的顺手的一种,说白了这终归就是一个工具,没什么好与坏之分,因人而异,目的都是为了提高工作效率