@alenon/grpc-mock-server

中文文档
3.2.9发布于 2026/05/09MITTypeScriptCommonJS构建来源已验证近 30 天下载 1.3万

gRPC 模拟服务器写入打字符

中文使用文档
文档目录23 节
  1. * 特性
  2. * 安装
  3. QQ 快速启动
  4. 使用实例
  5. Basic 示例 - 单一Proto 文件
  6. 高级示例 - 多个Proto 文件
  7. 测试示例
  8. API 参考
  9. GrpcMockServer
  10. 常见案件
  11. 自定义服务器地址
  12. 处理错误
  13. 方法链
  14. * 解决问题
  15. "好像包的名字错了"
  16. "好像服务名称错了"
  17. 导入带有多个 proto 文件的错误
  18. 已经使用的端口
  19. 实例
  20. 捐款
  21. 许可证
  22. 链接
  23. QQ 提示

grpc- mock- 服务器

一个轻量级,TypeScript-first gRPC模拟服务器,设计用于测试. 轻松创建模拟 GRPC 服务 .proto 没有复杂设置的文件.

NPM CI npm version License: MIT

* 特性

  • 🚀 0 配置 - 几秒钟后开始, 设置最小
  • 📦 类型脚本支持 - 使用类型脚本构建,包括类型定义
  • 🔧 弹性 - 支持具有交叉包装进口的单一和多原型文件
  • 🧪 试验友好 - 适合单位和综合测试
  • 🎯 简单 API - 干净、直观的界面
  • 🔄 自动/等待 - 基于现代承诺的API

* 安装

npm install @alenon/grpc-mock-server

或用纱线:

yarn add @alenon/grpc-mock-server

QQ 快速启动

仅用几行创建模拟服务器 :

import { GrpcMockServer } from '@alenon/grpc-mock-server';

// Create server instance
const server = new GrpcMockServer();

// Define your service implementations
const implementations = {
  GetUser: (call: any, callback: any) => {
    callback(null, { name: 'John Doe', id: '123' });
  }
};

// Add service from proto file
server.addService(
  './path/to/user.proto',
  'user',           // package name from proto
  'UserService',    // service name from proto
  implementations
);

// Start the server
await server.start();
console.log(`Server running at: ${server.serverAddress}`);

// Don't forget to stop when done!
await server.stop();

使用实例

Basic 示例 - 单一Proto 文件

这个例子显示了一个单一原型文件最简单的使用案例.

实例。 proto :

syntax = "proto3";

package com.alenon.example;

service ExampleService {
    rpc ex1 (ExampleRequest) returns (ExampleResponse) {}
}

message ExampleRequest {
    string msg = 1;
}

message ExampleResponse {
    string msg = 1;
}

示例:

import { GrpcMockServer } from '@alenon/grpc-mock-server';
import * as grpc from '@grpc/grpc-js';
import * as proto_loader from '@grpc/proto-loader';
import { ProtoUtils } from '@alenon/grpc-mock-server';

async function example() {
  const server = new GrpcMockServer();

  // Define implementations
  const implementations = {
    ex1: (call: any, callback: any) => {
      console.log('Received:', call.request.msg);
      callback(null, { msg: 'Hello from mock server!' });
    }
  };

  // Add service
  server.addService(
    __dirname + '/example.proto',
    'com.alenon.example',
    'ExampleService',
    implementations
  );

  // Start server
  await server.start();
  console.log(`Server listening at: ${server.serverAddress}`);

  // Create client and test
  const pkgDef = grpc.loadPackageDefinition(
    proto_loader.loadSync(__dirname + '/example.proto')
  );
  const proto = ProtoUtils.getProtoFromPkgDefinition('com.alenon.example', pkgDef);
  
  const client = new proto.ExampleService(
    server.serverAddress,
    grpc.credentials.createInsecure()
  );

  // Make request
  const response = await new Promise((resolve, reject) => {
    client.ex1({ msg: 'Hello!' }, (error: any, response: any) => {
      error ? reject(error) : resolve(response);
    });
  });

  console.log('Response:', response);
  
  await server.stop();
}

example().catch(console.error);

高级示例 - 多个Proto 文件

当您从其他软件包导入原生文件时, 请使用一系列原生路径 includeDirs数字 :

用户。 proto :

syntax = "proto3";

package user;

import "address.proto";

message User {
  string name = 1;
  common.Address address = 2;
}

service UserService {
  rpc GetUser (UserRequest) returns (UserResponse);
}

message UserRequest {
  string id = 1;
}

message UserResponse {
  User user = 1;
}

地址. proto: (中文(简体) )

syntax = "proto3";

package common;

message Address {
  string postal_code = 1;
  string city = 2;
  string country = 3;
}

多实例. ts:

import { GrpcMockServer } from '@alenon/grpc-mock-server';

async function multiProtoExample() {
  const server = new GrpcMockServer();

  const implementations = {
    GetUser: (call: any, callback: any) => {
      callback(null, {
        user: {
          name: 'John Doe',
          address: {
            postal_code: '12345',
            city: 'San Francisco',
            country: 'USA'
          }
        }
      });
    }
  };

  // Use array of proto files with options
  server.addService(
    [
      __dirname + '/user.proto',
      __dirname + '/address.proto'
    ],
    'user',
    'UserService',
    implementations,
    {
      includeDirs: [__dirname],  // Required for imports
      keepCase: true,             // Preserve field names
      longs: String,              // Convert longs to strings
      enums: String,              // Convert enums to strings
      defaults: true,             // Include default values
      oneofs: true                // Handle oneof fields
    }
  );

  await server.start();
  // ... use server ...
  await server.stop();
}

测试示例

适合 Jest 或其他测试框架:

import { GrpcMockServer, ProtoUtils } from '@alenon/grpc-mock-server';
import * as grpc from '@grpc/grpc-js';
import * as proto_loader from '@grpc/proto-loader';

describe('ExampleService Tests', () => {
  let server: GrpcMockServer;
  let client: any;

  beforeAll(async () => {
    server = new GrpcMockServer();
    
    server.addService(
      __dirname + '/example.proto',
      'com.alenon.example',
      'ExampleService',
      {
        ex1: (call: any, callback: any) => {
          callback(null, { msg: 'Test response' });
        }
      }
    );

    await server.start();

    // Setup client
    const pkgDef = grpc.loadPackageDefinition(
      proto_loader.loadSync(__dirname + '/example.proto')
    );
    const proto = ProtoUtils.getProtoFromPkgDefinition('com.alenon.example', pkgDef);
    client = new proto.ExampleService(
      server.serverAddress,
      grpc.credentials.createInsecure()
    );
  });

  afterAll(async () => {
    await server.stop();
  });

  it('should return response data', async () => {
    const response = await new Promise((resolve, reject) => {
      client.ex1({ msg: 'Test request' }, (error: any, response: any) => {
        error ? reject(error) : resolve(response);
      });
    });

    expect(response.msg).toBe('Test response');
  });
});

API 参考

GrpcMockServer

用于创建和管理模拟 gRPC 服务器的主类.

构造器

new GrpcMockServer(serverAddress?: string)
  • serverAddress (可选) : 格式服务器地址 host:port默认 : '127.0.0.1:50777'

方法

addService(protoPath, pkgName, serviceName, implementations, protoLoadOptions?)

向模拟服务器添加 gRPC 服务 .

参数:

  • protoPath数字 : string | string[] - 原始文件路径。 导入的多个文件使用数组 .
  • pkgName数字 : string - 您定义的软件包名称 .proto 文档.
  • serviceName数字 : string - 您定义的服务名称 .proto 文档.
  • implementations数字 : object - 将RPC方法名称映射到其执行中.
    • 每项执行都是一项职能: (call: any, callback: any) => void
    • 打电话 callback(null, response) 成绩
    • 打电话 callback(error) 错误
  • protoLoadOptions (可选) @grpc/proto-loader。共同选项:
    • includeDirs数字 : string[] - 搜索导入原生文件的目录
    • keepCase数字 : boolean - 保留字段名外壳( 默认 ): false(中文(简体) )
    • longs数字 : Function - 如何处理长值(例如, String(中文(简体) )
    • enums数字 : Function - 如何处理enum值(例如, String(中文(简体) )
    • defaults数字 : boolean - 包含默认值( 默认值 : false(中文(简体) )
    • oneofs数字 : boolean - 处理一个字段(默认: false(中文(简体) )

回返情况: GrpcMockServer (用于方法链)

start()

启动模拟服务器.

回返情况: Promise<GrpcMockServer>

stop()

优雅地停止模拟服务器 .

回返情况: Promise<GrpcMockServer>

serverAddress

属性 : string - 服务器在听的地址.

server

属性 : grpc.Server - 访问 GRPC 服务器实例.

常见案件

自定义服务器地址

const server = new GrpcMockServer('localhost:50051');

处理错误

import * as grpc from '@grpc/grpc-js';

const implementations = {
  GetUser: (call: any, callback: any) => {
    if (!call.request.id) {
      callback({ code: grpc.status.INVALID_ARGUMENT, message: 'ID required' });
      return;
    }
    callback(null, { name: 'User', id: call.request.id });
  }
};

方法链

await new GrpcMockServer()
  .addService(protoPath, pkgName, serviceName, impl1)
  .addService(protoPath2, pkgName2, serviceName2, impl2)
  .start();

* 解决问题

"好像包的名字错了"

  • 校验 pkgName 完全匹配 package 声明 .proto 文件
  • 检查打字和大小写灵敏度

"好像服务名称错了"

  • 校验 serviceName 匹配您的服务名称 .proto 文件
  • 检查打字和大小写灵敏度

导入带有多个 proto 文件的错误

  • 保证 includeDirs 包括包含导入原生文件的目录
  • 校验原始文件中的导入路径相对于 includeDirs
  • 使用 keepCase: true 如果您的原型使用蛇 case 字段名

已经使用的端口

  • 更改服务器地址 : new GrpcMockServer('127.0.0.1:50778')
  • 确保停止先前的服务器事件

实例

看看这个 示例目录 用于完整的工作示例:

运行示例 :

npm run example
npm run multi-proto-example

捐款

欢迎捐款! 请随意提交拉力请求.

许可证

麻省理工学院执照 - 看 自由主义 详细文件.

QQ 提示

  • 总是打电话 stop() 测试后清理资源
  • 使用 keepCase: true 如果您的原始文件使用蛇 case 命名
  • 对于复杂的原始结构,使用 defaults: true 财务报告和审定财务报表 oneofs: true
  • 服务器默认使用不安全的证书( 测试完美)

为GRPC测试社区制作

版本与发布记录

@alenon/grpc-mock-server 共发布 68 个版本,首次发布于 2020/06/04;过去 12 个月发布了 6 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.2.9latest2026/05/095 个月前
3.2.82026/04/186 个月前
3.2.72026/04/057 个月前
3.2.62026/02/078 个月前
3.2.52025/12/2510 个月前
3.2.42025/12/2510 个月前

关于 @alenon/grpc-mock-server 的常见问题

@alenon/grpc-mock-server 是什么?

gRPC 模拟服务器写入打字符

如何安装 @alenon/grpc-mock-server?

在项目目录运行 npm install @alenon/grpc-mock-server,或使用 pnpm add / yarn add / bun add。

@alenon/grpc-mock-server 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@alenon/grpc-mock-server 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@alenon/grpc-mock-server 可以商用吗?

@alenon/grpc-mock-server 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@alenon/grpc-mock-server 的下载量有多少?

根据 npm 官方下载统计,@alenon/grpc-mock-server 在 2026/10/06 – 2026/11/04 这 30 天内被下载 12,613 次,日均约 420 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@alenon/grpc-mock-server 还在维护吗?

最新版本 3.2.9 发布于 2026/05/09(5 个月前);至今共发布 68 个版本,其中过去 12 个月发布了 6 个;首次发布于 2020/06/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。