loading...

grpc-mock: A simple mock gRPC server on Node.js

yoshiyukikato profile image Yoshiyuki Kato ・3 min read

Hi, everyone! Happy new yearπŸŒ…

Unfortunately I had a bad cold at the very beginning of this year 😷
It was very boring for me to get a rest for some days, so I was developing a Node.js library grpc-mock, with lying down on my bed.

The grpc-mock enables you to build a gRPC mock server by only passing rules about respond. I think this will be useful when you write a test including gRPC calling 😎

Following is a simple example.

const {createMockServer} = require("grpc-mock");
const mockServer = createMockServer({
  protoPath: "/path/to/greeter.proto",
  packageName: "greeter",
  serviceName: "Greeter",
  rules: [
    { method: "hello", input: { message: "Hi" }, output: { message: "Hello" } }
  ]
});
mockServer.listen("0.0.0.0:50051");
syntax="proto3";

package greeter;

service Greeter {
  rpc Hello (RequestGreet) returns (ResponseGreet) {}
}

message RequestGreet {
  string message = 1;
}

message ResponseGreet {
  string message = 1;
}

A rule is described as an object.

{ method: "hello", input: { message: "Hi" }, output: { message: "Hello" } }

This rule make the gRPC server to respond by { message: "Hello" } when hello method called with { message: "Hi" }.

You can also specify the input pattern by Regular Expression string. Following is a rule makes the server to respond by { message: "Hello" } when hello method is called with any argument:

{ method: "hello", input: ".*", output: { message: "Hello" } }

Stream support

grpc-mock supports both of client/server stream. When using stream, you set an appropriate value to streamType property in a rule. Showing example rules with corresponding rpc definitions bellow.

Only client side stream

The server responds by { message: "I'm fine, thank you" } when it receives a streamed sequence of { message: "Hi" } and { message: "How are you?" } in a call of howAreYou method. Please set "client" to streamType property.

{
  method: "howAreYou",
  streamType: "client",
  stream: [
    { input: { message: "Hi" } },
    { input: { message: "How are you?" } },
  ],
  output: { message: "I'm fine, thank you" }
}
rpc HowAreYou (stream RequestGreet) returns (ResponseGreet) {}

Only server side stream

The server responds by a streamed sequence of { message: "Hi, I'm Sana" } and { message: "Nice to meet you too" } when niceToMeetYou method is called with { message: "Hi. I'm John. Nice to meet you" }. Please set "server" to streamType property.

{
  method: "niceToMeetYou",
  streamType: "server",
  stream: [
    { output: { message: "Hi, I'm Sana" } },
    { output: { message: "Nice to meet you too" } },
  ],
  input: { message: "Hi. I'm John. Nice to meet you" }
}
rpc NiceToMeetYou (RequestGreet) returns (stream ResponseGreet) {}

Mutual(client and server) stream

Mutual stream case might be a bit confusing. The server responds by { message: "Hi there" } when receiving { message: "Hi" }, and responds by { message: "I'm fine, thank you." } when receiving { message: "How are you?" } in a call of chat method. Where, inputs of { message: "Hi" } and { message: "How are you?" } must be sent in the order. Please set "mutual" to streamType property.

{
  method: "chat",
  streamType: "mutual",
  stream: [
    { input: { message: "Hi" }, output: { message: "Hi there" } },
    { input: { message: "How are you?" }, output: { message: "I'm fine, thank you." } },
  ]
}
rpc Chat (stream RequestGreet) returns (stream ResponseGreet) {}

Conclusion

In this post, I introduced grpc-mock that is a Node.js library for building gRPC mock server simply. This library is now in developing, your comment, Issue and PR are welcome πŸ€—

I'm very happy if the lib helps your coding.

YoshiyukiKato / grpc-mock

A simple mock gRPC server on Node.js

grpc-mock

npm version

A simple mock gRPC server on Node.js.

const {createMockServer} = require("grpc-mock")
const mockServer = createMockServer({
  protoPath: "/path/to/greeter.proto"
  packageName: "greeter"
  serviceName: "Greeter"
  rules: [
    { method: "hello", input: { message: "test" }, output: { message: "Hello" } },
    { method: "goodbye", input: ".*", output: { message: "Goodbye" } },
    
    {
      method: "howAreYou",
      streamType: "client",
      stream: [
        { input: { message: "Hi" } },
        { input: { message: "How are you?" } },
      ],
      output: { message: "I'm fine, thank you" }
    },
    
    {
      method
…

Discussion

pic
Editor guide
Collapse
deepikaj10 profile image
Deepikaj10

Hi I am trying to implement something like above at my end but I am getting error
Error: 3 INVALID_ARGUMENT: unexpected input pattern

I am making sure that the input and output is according to what is defined in proto