You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Docker运行的集成测试中Mock GRPC服务内的GRPC客户端

解决E2E测试中Mock gRPC客户端C的三种实用方案

针对你不想启动依赖复杂的客户端C容器的需求,下面是几个落地性强的Mock方案:

方案一:依赖注入+测试专用Mock客户端

核心思路是把客户端C的初始化逻辑做成可配置的,通过环境变量切换真实客户端和Mock实现,不需要额外启动服务。

步骤:

  1. 生成Mock客户端:用mockery或者github.com/golang/mock工具,根据客户端C的gRPC proto文件生成Mock实现。比如执行mockery --name S2ControlPlaneApiServiceClient --output mocks --outpkg mocks生成Mock代码。
  2. 修改API服务的客户端初始化逻辑:通过环境变量判断是否启用Mock:
import (
    "os"
    "log"
    "github.com/golang/mock/gomock"
    "your-project/protos"
    "your-project/mocks"
)

func main() {
    // ... 其他初始化逻辑(store、dd、zapLogger等)

    var client protos.S2ControlPlaneApiServiceClient
    mockEnabled := os.Getenv("MOCK_CONTROL_PLANE") == "true"

    if mockEnabled {
        ctrl := gomock.NewController(nil)
        defer ctrl.Finish()

        // 创建Mock客户端并预设方法行为
        mockClient := mocks.NewS2ControlPlaneApiServiceClient(ctrl)
        // 示例:预设SomeMethod的返回值,可根据测试需求添加更多
        mockClient.EXPECT().SomeMethod(gomock.Any()).Return(&protos.SomeResponse{}, nil)
        
        client = mockClient
    } else {
        // 真实客户端连接逻辑
        conn, err := grpc.Dial("localhost:38644", grpc.WithInsecure())
        if err != nil {
            log.Fatalf("failed to connect to control plane: %v", err)
        }
        defer conn.Close()
        client = protos.NewS2ControlPlaneApiServiceClient(conn)
    }

    s := service.NewDatalakeApiServiceImpl(client, store)
    // ... 后续gRPC服务器启动逻辑不变
}
  1. Docker Compose配置环境变量:
datalake_api:
    build:
      context: ../../../
      dockerfile: go.Dockerfile
    environment:
      - MOCK_CONTROL_PLANE=true

优点:

  • 不需要额外启动任何服务,Mock逻辑内嵌在API进程中
  • 可以精准控制每个方法的返回值,适合针对性测试

缺点:

  • Mock逻辑和业务代码耦合,需要维护环境变量判断分支

方案二:本地启动Mock gRPC服务器,容器指向宿主机

核心思路是在E2E测试运行时,本地启动一个Mock gRPC服务器,让容器内的API服务连接这个外部Mock服务。

步骤:

  1. 编写Mock服务器代码:实现客户端C的gRPC服务接口,预设方法行为:
import (
    "net"
    "log"
    "github.com/golang/mock/gomock"
    "google.golang.org/grpc"
    "your-project/protos"
    "your-project/mocks"
)

func main() {
    lis, err := net.Listen("tcp", ":38644")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }

    grpcServer := grpc.NewServer()
    ctrl := gomock.NewController(nil)
    mockService := mocks.NewS2ControlPlaneApiServiceServer(ctrl)

    // 预设服务方法的行为,比如处理API服务的调用请求
    mockService.EXPECT().SomeMethod(gomock.Any(), gomock.Any()).Return(&protos.SomeResponse{}, nil)

    protos.RegisterS2ControlPlaneApiServiceServer(grpcServer, mockService)
    log.Printf("mock control plane server listening on :38644")

    if err := grpcServer.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}
  1. 修改API服务的连接地址为环境变量配置:
addr := os.Getenv("CONTROL_PLANE_ADDR")
if addr == "" {
    addr = "localhost:38644"
}
conn, err := grpc.Dial(addr, grpc.WithInsecure())
// ... 后续逻辑
  1. Docker Compose配置指向宿主机:
datalake_api:
    build:
      context: ../../../
      dockerfile: go.Dockerfile
    environment:
      - CONTROL_PLANE_ADDR=host.docker.internal:38644
    # 如果是Linux环境,host.docker.internal可能不生效,需要添加网络配置:
    # network_mode: "host"

优点:

  • Mock逻辑和API服务完全解耦,可独立维护和扩展
  • 模拟真实的gRPC网络调用,测试场景更接近生产环境

缺点:

  • 需要在测试执行前手动/自动启动Mock服务器
  • 跨平台(比如Linux)可能需要调整网络配置

方案三:容器内嵌入轻量Mock服务

核心思路是把Mock服务器打包进API服务的Docker镜像,在测试环境启动时自动启动Mock服务,完全容器化,不需要外部依赖。

步骤:

  1. 多阶段构建Docker镜像:同时打包API服务和Mock服务器:
# 构建API服务
FROM golang:1.21 as api-builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o datalake-api ./cmd/api

# 构建Mock服务器
FROM golang:1.21 as mock-builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o mock-control-plane ./cmd/mock-control-plane

# 最终镜像
FROM alpine:latest
WORKDIR /app
COPY --from=api-builder /app/datalake-api .
COPY --from=mock-builder /app/mock-control-plane .
COPY entrypoint.sh .
RUN chmod +x entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
  1. 编写entrypoint启动脚本:判断是否启动Mock服务:
#!/bin/sh
# 启动Mock服务(后台运行)
if [ "$MOCK_CONTROL_PLANE" = "true" ]; then
    ./mock-control-plane &
fi
# 启动API服务
exec ./datalake-api
  1. Docker Compose配置环境变量:
datalake_api:
    build:
      context: ../../../
      dockerfile: go.Dockerfile
    environment:
      - MOCK_CONTROL_PLANE=true
      - CONTROL_PLANE_ADDR=localhost:38644

优点:

  • 完全容器化,测试环境不需要额外依赖
  • 可以在任何支持Docker的环境中运行,一致性强

缺点:

  • 镜像体积会略有增加
  • Mock服务和API服务共享容器资源,可能存在干扰风险

内容的提问来源于stack exchange,提问作者Anshum17

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 04:10:31