模拟API,如此简单:MSW和Faker.js的无缝集成指南

516 阅读5分钟

介绍

Mock Service Worker简称MSW, 是一个用于浏览器和Node.js的 API 模拟库。使用 MSW,你可以拦截浏览器或node服务器发出的网络请求、观察它们并使用模拟响应来响应它们

faker,注意此faker非彼faker⚠️,它是一个前端js库,用于生成大量虚假(但真实)的数据用于测试和开发,有时候你想造假数据,几个很容易,但是数量过多就有些乏力了,这时候可以使用该库批量生产。

使用msw拦截网络请求,使用faker生成测试数据,可以让你不依赖实际的 API 响应,帮助你在后端服务可能尚未就绪时、或者在进行前端测试时、或者你想开发纯前端项目时也能轻松的进行数据的请求和响应。

话不多说,进入状态...

MSW

image.png

  1. 安装
npm install msw@latest --save-dev

msw支持两种类型的 API 风格,一个是 REST API,一个是 GraphQL API。如果你不知道 GraphQL,不知道也没关系,知道 REST 风格 API 就行了,现在我们大部分项目用的都是 REST 风格,我会用REST 风格讲解。

  1. 编写请求处理程序,用来拦截请求并处理其响应

example.com/user 地址发送一个get请求,处理请求并相应json数据

import { http, HttpResponse } from 'msw'
 
export const handlers = [
  http.get('https://example.com/user', () => {
    return HttpResponse.json({
      id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d',
      firstName: '小新',
      lastName: '学研社',
    })
  }),
]

httpHttpResponse就相当于我们express当中的实例response对象,这里就相当于定义了一个get请求,请求路径为/user

  1. 集成

看你是要在浏览器中使用还是在Node.js进程中使用msw来进行网络拦截。

//node
import { setupServer } from 'msw/node'
import { handlers } from './handlers'
 
export const server = setupServer(...handlers)


//client
import { setupWorker } from "msw/browser";
import { handlers } from './handlers'

export const worker = setupWorker(...handlers);
  1. 启动

要开始请求拦截,需要在Node.js进程中调用 listen(),或者在浏览器客户端中调用start()

//node
server.listen()


//client
await worker.start()  // Promise<{ pending }>

start()是一个异步操作。 worker.start() 返回一个 promise,当其准备好时,该 promise 将解决。 一般会在入口文件中调用它。

  1. 浏览器中使用补充

在浏览器中使用msw是通过 Service Worker代理服务器 做请求拦截的,这块我们要单独启动个服务器服务 注册 Service Worker 并启动请求拦截。

代码无需自己编写,使用msw生成:

npx msw init public/ --save 

public文件夹下会生成一个mockServiceWorker.js,当程序运行时会自动注入到浏览器中启动并拦截。

这里--save指令会在package.json文件中生成文件所在位置的配置选项:

"msw": {
  "workerDirectory": [
    "public"
  ]
}
  1. msw 处于活动状态时,可以在浏览器的控制台中看到打印的确认消息。

image-20240805205822958.png

编码完成,当我们在客户端通过用户操作发起网络请求/user接口时,msw就会拦截该请求,将数据返回给客户端。

Faker

116eb7855c00680f12d786bf60574648.png

  1. 安装faker
npm install @faker-js/faker --save-dev
  1. 没什么可说的,直接用就完了
import { faker } from '@faker-js/faker';

const randomName = faker.person.fullName(); // Rowan Nikolaus
const randomEmail = faker.internet.email(); // Kassandra.Haley@erich.biz
const randomMusic = faker.music.genre(); // "Soul"

//随机名字,随机邮箱,随机音乐流派
console.log(randomName, randomEmail, randomMusic);




//生成一个在2023-01-01之后的日期
const time = faker.date.soon({ refDate: "2023-01-01T00:00:00.000Z" }); //Sun Jan 01 2023 23:54:43 GMT+0800 (中国标准时间)
console.log(time);
//生成一个uuid
const uuid = faker.string.uuid(); //b1ecd28c-2b3c-4031-9020-4e3fde4d88d9
console.log(uuid);




//设置seed,这样每次获取的都是相同值
faker.seed(123);
const firstRandom = faker.number.int();
console.log(firstRandom);//6273236744536064,每次都是6273236744536064,不是随机值

faker.seed(456);
const secondRandom = faker.number.int();
console.log(secondRandom);//2240594032197632

console.log(firstRandom === secondRandom); //false




//生成一个用户信息
const user = {
  _id: faker.string.uuid(),
  avatar: faker.image.avatar(),
  birthday: faker.date.birthdate(),
  email: faker.internet.email(),
  firstName: faker.person.firstName(),
  lastName: faker.person.lastName(),
  sex: faker.person.sexType(),
  subscriptionTier: faker.helpers.arrayElement(["free", "basic", "business"]),
};
console.log(user);

image-20240805213621654.png

  1. 如果你项目集成了 TypeScript,为了让其正常工作,需要检查你的tsconfig文件中是否正确设置了这些compilerOptions
{
  "compilerOptions": {
    "esModuleInterop": true,
    "moduleResolution": "Node"
  }
}
  1. faker内置了60多种语言,通过不同的对象来创建不用语言的测试数据。你应该也用不了这么多,随便举几个例子:
fakerZH_CN//简体中文
fakerZH_TW//繁体中文
fakerEN//英文
fakerDE//德文

import { fakerDE as faker } from "@faker-js/faker";

默认是输出英文。

最后

MSWFaker.js 的结合使用为前端开发提供了一个强大的模拟 API 请求的解决方案,掌握以上语法你使用网络请求拦截就游刃有余了,你可以在测试和开发过程中提供灵活的数据模拟,再也不用看后端的嘴脸啦!

在实际项目中你可以封装的更优雅一点,比如将接口拦截的处理和响应还有集成操作都放在mock文件夹下,应该是没毛病,如果你需要的话,这里有包含网络请求拦截的demo,并且封装了msw,在我的公众号里回复关键词:msw获取。

感谢您的阅读!

22.gif