MCPcopy Index your code
hub / github.com/bavix/gripmock

github.com/bavix/gripmock @v3.15.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v3.15.1 ↗ · + Follow
3,645 symbols 16,871 edges 357 files 890 documented · 24%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

GripMock

Coverage Status Go Report Card License: MIT

GripMock 🚀

语言版本: English | 简体中文

提示:本页面由机器翻译生成,内容可能存在不准确或不完整之处。请以英文原文 README.md 为准。

用于测试与开发的最快、最可靠的 gRPC Mock 服务器。

GripMock 可以根据你的 .proto 文件或编译后的 .pb 描述文件创建 Mock 服务器,让 gRPC 测试变得简单且高效。非常适合端到端测试、开发环境和 CI/CD 流水线。

greeter

✨ 功能特性

  • 原生运行时 - 单一进程内引擎,无需在运行时生成 gRPC 代码
  • 描述来源 - 可从 .proto、编译后的 .pb、BSR 模块或 gRPC reflection 加载 API
  • 动态 .pb 服务加载 - 可通过 API 在运行时加载编译后的 protobuf 描述文件,无需重启
  • 热 Stub 管理 - 通过 API/UI 创建、更新和删除 Stub,无需重启服务
  • 灵活匹配 - equalscontainsmatchesglob、headers、priority 和 match limits
  • 数组感知匹配 - 可选的数组顺序忽略能力,减少脆弱的测试断言
  • 动态模板 - 基于请求体、headers 与流上下文构建响应
  • 完整 gRPC 覆盖 - Unary、服务端流、客户端流与双向流
  • 错误、细节与延迟模拟 - 返回真实的 gRPC 状态码、details(Any)与响应时延
  • TLS 和 mTLS 支持 - 使用原生 TLS 选项运行安全的 gRPC/HTTP 测试环境
  • 高级 Protobuf 类型支持 - 支持 well-known 和 extended protobuf 类型(google.protobuf.*google.type.*
  • YAML/JSON + Schema - 支持两种 Stub 格式,并提供 JSON Schema IDE 校验
  • 插件生态 - 使用 Go 插件扩展函数,并可与 builder 镜像标签配套
  • 内置 Faker 模板 - 可在模板中直接生成真实风格的 person/contact/geo/network 测试数据(faker.*
  • OpenTelemetry 链路追踪 - 支持 gRPC 与 HTTP 路径的 OTLP 追踪(otelgrpc + otelhttp
  • Prometheus 指标(/metrics - 暴露运行时/进程指标(go_*process_*)以及 GripMock 指标
  • 运维 API - 健康检查端点、descriptors API、stubs API 以及 Web 控制台
  • Embedded SDK(实验性) - 在 Go 测试/服务中运行 GripMock,并提供验证助手
  • MCP API(实验性) - 提供可流式处理的 MCP 端点,用于 Agent 与工具集成
  • Upstream Modes(实验性) - proxyreplaycapture 模式,用于从真实上游服务渐进迁移到本地 mocks

📚 文档

完整文档 - 带示例的完整指南

  • Descriptor API(/api/descriptors:运行时加载编译后的 proto 描述文件(.pb),附带可验证的 curl 工作流:文档
  • Upstream Modes(实验性)proxyreplaycapture,包含实用的上线迁移指导:文档
  • Embedded SDK(实验性):进程内测试,支持 stubs、verification、sdk.By(fullMethod) 助手以及带上下文的远程校验:文档
  • Faker 参考:内置 faker 的逐键说明与示例:文档
  • OpenTelemetry + 指标:追踪环境变量与 /metrics 说明:文档
  • GitHub Actions(CI/CD):官方工作流 Action,可自动下载安装、启动、等待就绪并停止 GripMock:文档

🧬 项目演进

GripMock 最初是 tokopedia/gripmock 的一个 fork,随后演进为独立且完全重写的项目。

当前 GripMock 聚焦于实用测试工作流:

  • 原生进程内架构(无需运行时代码生成)
  • 灵活描述来源与运行时能力(热更新 stubs + descriptors API)
  • 面向生产场景测试能力(流式、模板、upstream modes、plugins、SDK、MCP)

架构细节与基准方法见:Performance Comparison

🖥️ Web 界面

gripmock-ui

访问 http://localhost:4771/ 可在 Web 控制台中可视化管理 stubs。

🚀 快速开始

安装

选择你偏好的安装方式:

Homebrew(推荐)

brew tap gripmock/tap
brew install --cask gripmock

Shell Script

curl -s https://raw.githubusercontent.com/bavix/gripmock/refs/heads/master/setup.sh | sh -s

PowerShell(Windows)

irm https://raw.githubusercontent.com/bavix/gripmock/refs/heads/master/setup.ps1 | iex

Docker

docker pull bavix/gripmock

如需构建插件,请使用配套 builder 镜像:

docker pull bavix/gripmock:v3.7.1-builder

Go Install

go install github.com/bavix/gripmock/v3@latest

基础用法

使用 .proto 文件启动:

gripmock service.proto

添加静态 stubs:

gripmock --stub stubs/ service.proto

直接从 Buf Schema Registry(BSR)加载 API:

gripmock --stub third_party/bsr/eliza buf.build/connectrpc/eliza

从在线 gRPC 服务 reflection 加载 API:

gripmock grpc://localhost:50051
gripmock grpcs://api.company.local:443

可选参数:

gripmock grpc://localhost:50051?timeout=10s
gripmock grpcs://10.0.0.5:8443?serverName=api.company.local
gripmock grpc://localhost:50051?bearer=<token>

在 reflection 基础上使用 upstream modes(实验性):

# 通过 GripMock 进行纯反向代理
gripmock grpc+proxy://localhost:50051

# 本地 stubs 优先,matcher 未命中时回退上游
gripmock grpc+replay://localhost:50051

# replay + 将上游未命中自动录制为 GripMock stubs
gripmock grpc+capture://localhost:50051

私有 BSR 模块:

BSR_BUF_TOKEN=<token> gripmock --stub stubs/ buf.build/acme/private-api

自托管 BSR:

BSR_SELF_BASE_URL=https://bsr.company.local \
BSR_SELF_TOKEN=<token> \
gripmock --stub stubs/ bsr.company.local/team/payments

使用 Docker:

docker run -p 4770:4770 -p 4771:4771 \
  -v $(pwd)/stubs:/stubs \
  -v $(pwd)/proto:/proto \
  bavix/gripmock --stub=/stubs /proto/service.proto
  • 端口 4770:gRPC 服务
  • 端口 4771:Web UI 和 REST API

可观测性(v3.10.0)

OTEL_ENABLED=true \
OTEL_EXPORTER_OTLP_ENDPOINT=localhost:4317 \
OTEL_EXPORTER_OTLP_INSECURE=true \
gripmock --stub stubs/ service.proto
  • GET /metrics 始终可用
  • 仅在 OTEL_ENABLED=true 时启用追踪导出

🤖 GitHub Actions(CI/CD)

在 CI 流水线中使用官方 Action bavix/gripmock-action 运行 GripMock。

name: test

on: [push, pull_request]

jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - name: Start GripMock
        uses: bavix/gripmock-action@v1
        with:
          source: proto/service.proto
          stub: stubs

      - name: Run tests
        run: go test ./...

该 Action 会:

  • 从 GitHub Releases 下载 GripMock(二进制版本可用 latest 或固定 version
  • 后台启动 GripMock,并等待就绪(/api/health/readiness
  • 通过 outputs 暴露地址(grpc-addrhttp-addr)供后续测试步骤使用
  • 在 post step 自动停止 GripMock

更多示例与完整 inputs/outputs 见:GitHub Actions 指南

📖 示例

examples 目录查看完整示例:

  • Streaming - 服务端、客户端与双向流
  • File Uploads - 分片文件上传测试
  • Real-time Chat - 双向通信
  • Data Feeds - 持续数据流
  • Authentication - 基于 Header 的认证测试
  • Performance - 高吞吐场景

Greeter:动态 stub 演示

Stub(通用):

# yaml-language-server: $schema=https://bavix.github.io/gripmock/schema/stub.json
# examples/projects/greeter/stub_say_hello.yaml
- service: helloworld.Greeter
  method: SayHello
  input:
    matches:
      name: ".+"
  output:
    data:
      message: "Hello, {{.Request.name}}!"  # dynamic template lives in output

说明: - 动态模板只放在 output 中(例如 dataheadersstream)。 - 保持 input 匹配为静态(equals/contains/matches 中不要使用 {{ ... }})。

# 启动服务
go run main.go examples/projects/greeter/service.proto --stub examples/projects/greeter

# 通过 grpcurl 调用
grpcurl -plaintext -d '{"name":"Alex"}' localhost:4770 helloworld.Greeter/SayHello

期望响应:

{
  "message": "Hello, Alex!"
}

🔧 Stub 配置

基础 Stub 示例

service: Greeter
method: SayHello
input:
  equals:
    name: "gripmock"
output:
  data:
    message: "Hello GripMock!"

高级功能

优先级系统:

- service: UserService
  method: GetUser
  priority: 100  # Higher priority
  input:
    equals:
      id: "admin"
  output:
    data:
      role: "administrator"

- service: UserService
  method: GetUser
  priority: 1    # Lower priority (fallback)
  input:
    contains:
      id: "user"
  output:
    data:
      role: "user"

流式支持:

service: TrackService
method: StreamData
input:
  equals:
    sensor_id: "GPS001"
output:
  stream:
    - position: {"lat": 40.7128, "lng": -74.0060}
      timestamp: "2024-01-01T12:00:00Z"
    - position: {"lat": 40.7130, "lng": -74.0062}
      timestamp: "2024-01-01T12:00:05Z"

动态模板

GripMock 在 output 区域支持 Go text/template 语法的动态模板。

  • 访问请求字段:{{.Request.field}}
  • 访问请求头:{{.Headers.header_name}}
  • 客户端流上下文:{{.Requests}}(接收消息切片)、{{len .Requests}}{{(index .Requests 0).field}}
  • 双向流:{{.MessageIndex}} 给出当前消息索引(从 0 开始)
  • 数学辅助函数:sumavgmulminmaxaddsubdiv
  • 通用函数:jsonsplitjoinupperlowertitlesprintfintint64floatroundfloorceil
  • 内置 faker:faker.Person.*faker.Contact.*faker.Geo.*faker.Network.*faker.Identity.*

重要规则: - 不要在 input.equalsinput.containsinput.matches 中使用动态模板(匹配必须是静态的) - 对于服务端流,如果同时设置了 output.streamoutput.error/output.code,会先发送消息再返回错误;如果 output.stream 为空,会立即返回错误

Header 匹配:

service: AuthService
method: ValidateToken
headers:
  equals:
    authorization: "Bearer valid-token"
input:
  equals:
    token: "abc123"
output:
  data:
    valid: true
    user_id: "user123"

🔍 输入匹配

GripMock 提供四种强大的匹配策略:

1. 精确匹配(equals

input:
  equals:
    name: "gripmock"
    age: 25
    active: true

2. 部分匹配(contains

input:
  contains:
    name: "grip"  # Matches "gripmock", "gripster", etc.

3. 正则匹配(matches

input:
  matches:
    email: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
    phone: "^\\+?[1-9]\\d{1,14}$"

4. Glob 匹配(glob

input:
  glob:
    filename: "*.txt"
    path: "/usr/local/*"

🛠️ API

REST API 端点

  • GET /api/stubs - 列出所有 stubs
  • POST /api/descriptors - 在运行时加载 protobuf descriptor set(FileDescriptorSet
  • POST /api/stubs - 添加新 stub
  • POST /api/stubs/search - 查找匹配的 stub
  • DELETE /api/stubs - 清空所有 stubs
  • GET /api/health/liveness - 健康检查
  • GET /api/health/readiness - 就绪检查

API 使用示例

# Add a stub
curl -X POST http://localhost:4771/api/stubs \
  -H "Content-Type: application/json" \
  -d '{
    "service": "Greeter",
    "method": "SayHello",
    "input": {"equals": {"name": "world"}},
    "output": {"data": {"message": "Hello World!"}}
  }'

# Search for matching stub
curl -X POST http://localhost:4771/api/stubs/search \
  -H "Content-Type: application/json" \
  -d '{
    "service": "Greeter",
    "method": "SayHello",
    "data": {"name": "world"}
  }'

📋 JSON Schema 支持

为 stub 文件添加 schema 校验以获得 IDE 支持:

JSON 文件:

{
  "$schema": "https://bavix.github.io/gripmock/schema/stub.json",
  "service": "MyService",
  "method": "MyMethod"
}

YAML 文件:

# yaml-language-server: $schema=https://bavix.github.io/gripmock/schema/stub.json
service: MyService
method: MyMethod

🌐 BSR 集成

GripMock 支持与 Buf Schema Registry 的简化集成:

配置

# Public BSR (default)
BSR_BUF_BASE_URL=https://buf.build
BSR_BUF_TOKEN=<token>

# Self-hosted BSR
BSR_SELF_BASE_URL=https://bsr.company.local
BSR_SELF_TOKEN=<token>

使用

# Public module
gripmock buf.build/connectrpc/eliza

# Self-hosted module
gripmock bsr.company.local/team/payments:main

# With stubs
gripmock --stub stubs/ bsr.company.local/team/payments

路由

GripMock 会自动路由模块: - buf.build/owner/repo → 使用 Buf profile - bsr.company.local/owner/repo → 使用 Self profile

详情见 BSR Documentation

🔎 gRPC Reflection Source

GripMock 支持通过以下端点 scheme 从 gRPC reflection 加载 descriptors:

  • grpc://host:port(不安全)
  • grpcs://host:port(TLS)

支持的 query 参数:

  • timeout(默认 5s
  • bearer(Authorization token)
  • serverName(TLS SNI override)

示例:

gripmock grpc://localhost:50051
gripmock grpcs://api.company.local:443
gripmock grpcs://10.0.0.5:8443?serverName=api.company.local

完整指南:gRPC Reflection Source

🔁 Upstream Modes(实验性)

⚠️ 实验性功能:Upstream modes 可能在未提前通知的情况下变更。

Upstream modes 叠加在 reflection sources 之上,定义运行时行为:

  • proxy - 纯反向代理
  • replay - 本地优先 + 上游回退
  • capture - replay + 从上游自动录制 stub

模式指南:

📊 基准图表

Image size benchmark Startup readiness benchmark Latency percentiles benchmark Throughput benchmark

🔗 有用资源

🤝 参与贡献

欢迎贡献!详情请见我们的 Contributing Guide(中文版:CONTRIBUTING.zh-CN.md)。

📄 许可证

本项目基于 MIT License,详见 LICENSE 文件。


由 GripMock 社区用 ❤️ 打造

Extension points exported contracts — how you extend this code

BSRClient (Interface)
(no doc) [9 implementers]
internal/domain/protoset/bsr.go
Extender (Interface)
Extender defines the interface for extending stub functionality. [4 implementers]
internal/app/rest_server.go
Mock (Interface)
Mock represents a running gRPC mock server. [2 implementers]
pkg/sdk/mock.go
Result (Interface)
Result interface for testing - allows mocking stuber.Result. [2 implementers]
internal/infra/errors/formatter.go
Registry (Interface)
(no doc) [3 implementers]
pkg/plugins/registry.go
Option (FuncType)
(no doc)
internal/deps/builder.go
SourceHandler (Interface)
(no doc) [6 implementers]
internal/domain/protoset/source_handler.go
ToolHandler (FuncType)
(no doc)
internal/app/usecase/mcp/dispatch.go

Core symbols most depended-on inside this repo

Context
called by 583
pkg/sdk/verify.go
New
called by 337
internal/infra/stuber/inspect_finder_factory.go
Len
called by 328
internal/infra/stuber/stub.go
Error
called by 282
pkg/sdk/verify.go
Found
called by 174
internal/infra/errors/formatter.go
PutMany
called by 141
internal/infra/stuber/stuber.go
NewBudgerigar
called by 136
internal/infra/stuber/stuber.go
WriteHeader
called by 133
internal/infra/muxmiddleware/response_writer.go

Shape

Function 1,923
Method 1,354
Struct 283
Interface 59
TypeAlias 15
FuncType 11

Languages

Go100%

Modules by API surface

internal/domain/rest/api.gen.go131 symbols
internal/app/rest_server.go128 symbols
internal/app/grpc_server.go106 symbols
internal/infra/faker/contracts.go78 symbols
internal/app/rest_server_internal_test.go77 symbols
pkg/sdk/internal/examplefds/gen/examples/projects/multiverse/service.pb.go72 symbols
pkg/sdk/stub.go60 symbols
internal/infra/stuber/stuber_v2_test.go60 symbols
internal/infra/plugins/builtins.go55 symbols
internal/infra/stuber/storage.go48 symbols
pkg/sdk/sdk_test.go46 symbols
internal/domain/rest/api_gen_internal_test.go44 symbols

For agents

$ claude mcp add gripmock \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact