使用 npm 安装:
npm i mock-pb-cli@latest -g
可以使用下面命令查看帮助:
$ mock-pb -h
Usage: mock-protobuf [options] [command]
A tool to mock protobuf
Options:
  -v, --version         output the version number
  -h, --help            display help for command
Commands:
  s|serve [options]     Create a mock server for the given protobuf
  g|generate [options]  Generate mock data for the given protobuf
  help [command]        display help for command
有两个子命令:
mock-pb g 或 mock-pb generate:Mock JSON 数据;mock-pb s or mock-pb serve:Mock 服务;Generate 子命令主要是用来生成 Mock 的 JSON 数据;
例如:
$ mock-pb g
上面的命令会获取当前工作目录下所有的 Proto 文件,并且将 Mock 的数据输出到终端;
例如:
Mocked demo.BasicResponse:
{
    "status": 902735693509892,
    "message": "Vmucue hqxllqx oiloapzwp.",
    "resp": {}
}
Mocked demo.DemoRequest:
{
    "data": "Kqr gxxq."
}
Mocked demo.DemoResponse:
{
    "resp": {
        "status": -6061376970430480,
        "message": "Xpjzjyxrcq eqkmytjo.",
        "resp": {}
    },
    "resp_data": "Ryogd tswayqjsf."
}
默认情况下的 Protobuf 文件搜索路线为 .,你也可以使用 -d 来指定路径!
例如:
$ mock-pb g -d ../test/proto
同时,默认情况下 Mock 数据会打印到终端,你也可以使用 -o 来指定将 Mock 的数据输出到指定的目录!
例如:
$ mock-pb g -o ./mock-pb-output
此时,mock-pb-output 目录下的结果为:
$ tree
.
├── demo
│   ├── BasicResponse.json
│   ├── DemoRequest.json
│   └── DemoResponse.json
├── google.api
│   ├── CustomHttpPattern.json
│   ├── HttpBody.json
│   ├── Http.json
│   └── HttpRule.json
└── google.protobuf
    ├── Any.json
    ├── Api.json
		......
    ├── SourceContext.json
    ├── Type.json
    └── UninterpretedOption.json
输出中的目录结构是根据 Proto 文件中的 package 来产生的!
除了产生 Mock 的数据,也可以直接 Mock 服务接口;
下面的命令会读取当前工作目录下的 Proto 文件,并 Mock 在 Service 中定义了的 Method:
$ mock-pb s
输出如下:
Handling routePath: /Demo
Handling routePath: /demo/DemoServiceAnotherDemo
restify listening at http://[::]:3333
在服务端启动时,会打印出每个接口的请求路径;
默认情况下的服务端口号为:
3333,你可以使用-p来自定义端口;例如:
mock-pb s -p 13333
如果你在你的 Method 中通过 google.api.http 定义了请求路径,那么在 Mock 服务的时候会使用这个路径;
例如:
service DemoService {
  rpc Demo(DemoRequest) returns (DemoResponse) {
    option (google.api.http) = {
      post: "/Demo"
      body: "*"
    };
  }
}
如果没有指定请求路径,那么请求路径为:/{ProtobufPackageName}/{ProtobufMethodName};
例如:
syntax = "proto3";
package demo;
service DemoService {
  rpc AnotherDemo(AnotherDemoRequest) returns (AnotherDemoResponse) {}
}
当服务启动后的请求路径为:
$ curl localhost:3333/demo/DemoServiceAnotherDemo
{"resp":{"status":-843357854531144,"message":"Vzby.","resp":{}},"resp_data":"Kvia gfkcggmuo."}
有时候你可能并不想 Mock 一些像下面这些无意义的数据:
{"resp":{"status":-843357854531144,"message":"Vzby.","resp":{}},"resp_data":"Kvia gfkcggmuo."}
而是想要自定义一些有用的返回值,比如:
{"resp":{"status":200,"message":"ok"},"resp_data":{"Message":"This is a demo message"}}
此时可以创建配置文件,例如:
mock-protobuf.config.json
{
    "ResponseValue": [
        {
            "MethodName": "demo.Demo",
            "Data": {
                "Hello": "world"
            }
        },
        {
            "MethodName": "demo.AnotherDemo",
            "Data": {
                "resp": {
                    "status": 200,
                    "message": "ok"
                },
                "resp_data": {
                    "Message": "This is a demo message"
                }
            }
        }
    ]
}
其中 MethodName 是 Proto 文件中 Method 的全名:package.method;
同时,你也可以通过 -c 请求来指定你的配置文件路径,例如: -c ./mock-protobuf.config.json;
下面是一个完整的命令行例子:
$ npm run dev -- s -i demo -c ./mock-protobuf.config-demo.json
使用自定义返回值后的响应如下:
$ curl localhost:3333/Demo
{"Hello":"world"}
$ curl localhost:3333/demo/DemoServiceAnotherDemo
{"resp":{"status":200,"message":"ok"},"resp_data":{"Message":"This is a demo message"}}
有的时候我们并不想 Mock 所有的 Proto 定义,此时可以使用 Filter 过滤条件;
有两种方式进行过滤:
-i <string> 或 --include;-e <string> 或 --exclude;上面的 <string> 被定义为一个 JS 中的正则表达式 RegExp,所以可以使用类似于正则表达式的方式对 Proto 定义进行匹配:packageName.serviceName.methodName;
多个条件使用
,分隔!
当使用 Include 过滤条件,只有匹配的 Proto 定义才会被 Mock ;
例如:
$ mock-pb g -i demo
Mocked demo.BasicResponse:
{
    "status": -978663427598816,
    "message": "Iymo zomttydmb.",
    "resp": {}
}
Mocked demo.DemoRequest:
{
    "data": "Mdnbfxbvoq khrbwyu sxmkev jss."
}
Mocked demo.DemoResponse:
{
    "resp": {
        "status": 6207610394471496,
        "message": "Dkwse mmhmuhhunb.",
        "resp": {}
    },
    "resp_data": "Fqwkd noiefpr ntjbcfydl."
}
Mocked demo.AnotherDemoRequest:
{
    "name": "Puvujqy kyxl hshuysly.",
    "age": 175838119803604
}
Mocked demo.AnotherDemoResponse:
{
    "resp": {
        "status": -7659482750118844,
        "message": "Fygec kyzysqqga svimupy nbfrjt.",
        "resp": {}
    },
    "resp_data": "Mpgjtjsbr qfspgkb xmpji."
}
上面的命令只会为 demo.* 产生 Mock 数据(即:package 为 demo 的那些定义)!
另外一个例子:
$ mock-pb g -i demo.DemoRequest.*
Mocked demo.DemoRequest:
{
    "data": "Ewqzspj hjkfvvc froqdhkwe fkqsdg dytidwli."
}
此时只会 Mock:demo.DemoRequest 这一个 Message !
相反的,-e 产生将会排除那些匹配的 Message ;
例如:
$ mock-pb g -e demo.*,google.protobuf.* -o mock-pb-gen
$ tree
.
└── google.api
    ├── CustomHttpPattern.json
    ├── HttpBody.json
    ├── Http.json
    └── HttpRule.json
上面的命令将不会 Mock  demo.* 和 google.protobuf.* 下的 Message !
<font color="#f00">注意:当你同时使用  include and exclude 两个过滤器,exclude 会永远首先生效!</font>
例如:
$ mock-pb g -i demo -e demo
什么都不会输出,因为所有的内容都被过滤掉了!
关于整个开发的过程以及思路,我也放到了我的博客:
希望对 TypeScript 初学者,以及想使用 TypeScript 编写 CLI 小工具的小伙伴们有帮助!❤️