# Packages
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
# README
⚠️ From
v0.20.0
, the project will be rebranded togo.nhat.io/grpcmock
.v0.19.0
is the last version withgithub.com/nhatthm/grpcmock
.
gRPC Test Utilities for Golang
Test gRPC service and client like a pro.
Table of Contents
Prerequisites
Go >= 1.21
Install
go get go.nhat.io/grpcmock
Usage
Mock a gRPC server
Read more about mocking a gRPC server
Unary Method
Read more about mocking a Unary Method
package main
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"go.nhat.io/grpcmock"
xassert "go.nhat.io/grpcmock/assert"
)
func TestGetItems(t *testing.T) {
t.Parallel()
expected := &Item{Id: 42, Name: "Item 42"}
_, d := grpcmock.MockServerWithBufConn(
grpcmock.RegisterService(RegisterItemServiceServer),
func(s *grpcmock.Server) {
s.ExpectUnary("myservice/GetItem").
WithHeader("locale", "en-US").
WithPayload(&GetItemRequest{Id: 42}).
Return(expected)
},
)(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
out := &Item{}
err := grpcmock.InvokeUnary(ctx,
"myservice/GetItem",
&GetItemRequest{Id: 42}, out,
grpcmock.WithHeader("locale", "en-US"),
grpcmock.WithContextDialer(d),
grpcmock.WithInsecure(),
)
xassert.EqualMessage(t, expected, out)
assert.NoError(t, err)
}
Client-Stream Method
Read more about mocking a Client-Stream Method
package main
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"go.nhat.io/grpcmock"
xassert "go.nhat.io/grpcmock/assert"
)
func TestCreateItems(t *testing.T) {
t.Parallel()
expected := &CreateItemsResponse{NumItems: 1}
_, d := grpcmock.MockServerWithBufConn(
grpcmock.RegisterService(RegisterItemServiceServer),
func(s *grpcmock.Server) {
s.ExpectClientStream("myservice/CreateItems").
WithPayload([]*Item{{Id: 42}}).
Return(expected)
},
)(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
out := &CreateItemsResponse{}
err := grpcmock.InvokeClientStream(ctx, "myservice/CreateItems",
grpcmock.SendAll([]*Item{{Id: 42}}), out,
grpcmock.WithContextDialer(d),
grpcmock.WithInsecure(),
)
xassert.EqualMessage(t, expected, out)
assert.NoError(t, err)
}
Server-Stream Method
Read more about mocking a Server-Stream Method
package main
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"go.nhat.io/grpcmock"
xassert "go.nhat.io/grpcmock/assert"
)
func TestListItems(t *testing.T) {
t.Parallel()
expected := []*Item{
{Id: 41, Name: "Item 41"},
{Id: 42, Name: "Item 42"},
}
_, d := grpcmock.MockServerWithBufConn(
grpcmock.RegisterService(RegisterItemServiceServer),
func(s *grpcmock.Server) {
s.ExpectServerStream("myservice/ListItems").
WithPayload(&ListItemsRequest{}).
Return(expected)
},
)(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
actual := make([]*Item, 0)
err := grpcmock.InvokeServerStream(ctx,
"myservice/ListItems",
&ListItemsRequest{},
grpcmock.RecvAll(&actual),
grpcmock.WithContextDialer(d),
grpcmock.WithInsecure(),
)
assert.NoError(t, err)
assert.Len(t, actual, len(expected))
for i := 0; i < len(expected); i++ {
xassert.EqualMessage(t, expected[i], actual[i])
}
}
Bidirectional-Stream Method
Read more about mocking a Bidirectional-Stream Method
package main
import (
"context"
"errors"
"fmt"
"io"
"testing"
"time"
"github.com/stretchr/testify/assert"
"go.nhat.io/grpcmock"
xassert "go.nhat.io/grpcmock/assert"
"google.golang.org/grpc"
)
func TestTransformItems(t *testing.T) {
t.Parallel()
expected := []*Item{
{Id: 41, Name: "Item 41"},
{Id: 42, Name: "Item 42"},
}
_, d := grpcmock.MockServerWithBufConn(
grpcmock.RegisterService(RegisterItemServiceServer),
func(s *grpcmock.Server) {
s.ExpectBidirectionalStream("myservice/TransformItems").
Run(func(ctx context.Context, s grpc.ServerStream) error {
for {
item := &Item{}
err := s.RecvMsg(item)
if errors.Is(err, io.EOF) {
return nil
}
if err != nil {
return err
}
item.Name = fmt.Sprintf("Modified #%d", item.Id)
if err := s.SendMsg(item); err != nil {
return err
}
}
})
},
)(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
in := []*Item{
{Id: 41, Name: "Item 41"},
{Id: 42, Name: "Item 42"},
}
actual := make([]*Item, 0)
err := grpcmock.InvokeBidirectionalStream(ctx,
"myservice/TransformItems",
grpcmock.SendAndRecvAll(in, &actual),
grpcmock.WithContextDialer(d),
grpcmock.WithInsecure(),
)
assert.NoError(t, err)
assert.Len(t, actual, len(expected))
for i := 0; i < len(expected); i++ {
xassert.EqualMessage(t, expected[i], actual[i])
}
}
Invoke a gRPC method
Unary Method
package main
import (
"context"
"time"
"go.nhat.io/grpcmock"
"google.golang.org/grpc/test/bufconn"
)
func getItem(l *bufconn.Listener, id int32) (*Item, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
out := &Item{}
err := grpcmock.InvokeUnary(ctx, "myservice/GetItem",
&GetItemRequest{Id: id}, out,
grpcmock.WithHeader("Locale", "en-US"),
grpcmock.WithBufConnDialer(l),
grpcmock.WithInsecure(),
)
return out, err
}
Client-Stream Method
package main
import (
"context"
"time"
"go.nhat.io/grpcmock"
"google.golang.org/grpc/test/bufconn"
)
func createItems(l *bufconn.Listener, items []*Item) (*CreateItemsResponse, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
out := &CreateItemsResponse{}
err := grpcmock.InvokeClientStream(ctx, "myservice/CreateItems",
grpcmock.SendAll(items), out,
grpcmock.WithBufConnDialer(l),
grpcmock.WithInsecure(),
)
return out, err
}
Or with a custom handler
package main
import (
"context"
"time"
"go.nhat.io/grpcmock"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
)
func createItems(l *bufconn.Listener, items []*Item) (*CreateItemsResponse, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
out := &CreateItemsResponse{}
err := grpcmock.InvokeClientStream(ctx, "myservice/CreateItems",
func(s grpc.ClientStream) error {
// Handle the stream here.
return nil
},
out,
grpcmock.WithBufConnDialer(l),
grpcmock.WithInsecure(),
)
return out, err
}
Server-Stream Method
package main
import (
"context"
"time"
"go.nhat.io/grpcmock"
"google.golang.org/grpc/test/bufconn"
)
func listItems(l *bufconn.Listener) ([]*Item, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
out := make([]*Item, 0)
err := grpcmock.InvokeServerStream(ctx, "myservice/ListItems",
&ListItemsRequest{},
grpcmock.RecvAll(&out),
grpcmock.WithBufConnDialer(l),
grpcmock.WithInsecure(),
)
return out, err
}
Or with a custom handler
package main
import (
"context"
"time"
"go.nhat.io/grpcmock"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
)
func listItems(l *bufconn.Listener) ([]*Item, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
out := make([]*Item, 0)
err := grpcmock.InvokeServerStream(ctx, "myservice/ListItems",
&ListItemsRequest{},
func(s grpc.ClientStream) error {
// Handle the stream here.
return nil
},
grpcmock.WithBufConnDialer(l),
grpcmock.WithInsecure(),
)
return out, err
}
Bidirectional-Stream Method
package main
import (
"context"
"time"
"go.nhat.io/grpcmock"
"google.golang.org/grpc/test/bufconn"
)
func transformItems(l *bufconn.Listener, in []*Item) ([]*Item, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
out := make([]*Item, 0)
err := grpcmock.InvokeBidirectionalStream(ctx, "myservice/TransformItems",
grpcmock.SendAndRecvAll(in, &out),
grpcmock.WithBufConnDialer(l),
grpcmock.WithInsecure(),
)
return out, err
}
Or with a custom handler
package main
import (
"context"
"time"
"go.nhat.io/grpcmock"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
)
func transformItems(l *bufconn.Listener, in []*Item) ([]*Item, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()
out := make([]*Item, 0)
err := grpcmock.InvokeBidirectionalStream(ctx, "myservice/TransformItems",
func(s grpc.ClientStream) error {
// Handle the stream here.
return nil
},
grpcmock.WithBufConnDialer(l),
grpcmock.WithInsecure(),
)
return out, err
}
Donation
If this project help you reduce time to develop, you can give me a cup of coffee :)
Paypal donation
or scan this
