grpcstub provides gRPC server and client conn ( *grpc.ClientConn
) for stubbing, for testing in Go.
There is an HTTP version stubbing tool with the same design concept, httpstub.
package myapp
import (
"io"
"net/http"
"testing"
"github.com/k1LoW/grpcstub"
"github.com/k1LoW/myapp/protobuf/gen/go/routeguide"
)
func TestClient(t *testing.T) {
ctx := context.Background()
ts := grpcstub.NewServer(t, "path/to/protobuf")
t.Cleanup(func() {
ts.Close()
})
ts.Method("GetFeature").Response(&routeguite.Feature{
Name: "hello",
Location: &routeguide.Point{
Latitude: 10,
Longitude: 13,
},
})
// OR
// ts.Method("GetFeature").Response(map[string]any{"name": "hello", "location": map[string]any{"latitude": 10, "longitude": 13}})
client := routeguide.NewRouteGuideClient(ts.Conn())
if _, err := client.GetFeature(ctx, &routeguide.Point{
Latitude: 10,
Longitude: 13,
}); err != nil {
t.Fatal(err)
}
{
got := len(ts.Requests())
if want := 1; got != want {
t.Errorf("got %v\nwant %v", got, want)
}
}
req := ts.Requests()[0]
{
got := int32(req.Message["longitude"].(float64))
if want := int32(13); got != want {
t.Errorf("got %v\nwant %v", got, want)
}
}
}
grpcstub can return responses dynamically using the protocol buffer schema.
ts := grpcstub.NewServer(t, "path/to/protobuf")
t.Cleanup(func() {
ts.Close()
})
ts.ResponseDynamic()
ts := grpcstub.NewServer(t, "path/to/protobuf")
t.Cleanup(func() {
ts.Close()
})
ts.Service("routeguide.RouteGuide").Method("GetFeature").ResponseDynamic()
ts := grpcstub.NewServer(t, "path/to/protobuf")
t.Cleanup(func() {
ts.Close()
})
fk := faker.New()
want := time.Now()
opts := []GeneratorOption{
Generator("*_id", func(req *grpcstub.Request) any {
return fk.UUID().V4()
}),
Generator("*_time", func(req *grpcstub.Request) any {
return want
}),
}
ts.ResponseDynamic(opts...)
- monlabs/grpc-mock: Run a gRPC mock server by using protobuf reflection.