Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nhatthm/grpcmock
gRPC Test Utilities for Golang
https://github.com/nhatthm/grpcmock
go golang grpc mock test
Last synced: 7 days ago
JSON representation
gRPC Test Utilities for Golang
- Host: GitHub
- URL: https://github.com/nhatthm/grpcmock
- Owner: nhatthm
- License: mit
- Created: 2021-10-28T21:52:51.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2024-10-13T12:44:54.000Z (about 1 month ago)
- Last Synced: 2024-10-29T16:06:48.772Z (22 days ago)
- Topics: go, golang, grpc, mock, test
- Language: Go
- Homepage:
- Size: 542 KB
- Stars: 75
- Watchers: 3
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
> ⚠️ From `v0.20.0`, the project will be rebranded to `go.nhat.io/grpcmock`. `v0.19.0` is the last version with `github.com/nhatthm/grpcmock`.
# gRPC Test Utilities for Golang
[![GitHub Releases](https://img.shields.io/github/v/release/nhatthm/grpcmock)](https://github.com/nhatthm/grpcmock/releases/latest)
[![Build Status](https://github.com/nhatthm/grpcmock/actions/workflows/test.yaml/badge.svg)](https://github.com/nhatthm/grpcmock/actions/workflows/test.yaml)
[![codecov](https://codecov.io/gh/nhatthm/grpcmock/branch/master/graph/badge.svg?token=eTdAgDE2vR)](https://codecov.io/gh/nhatthm/grpcmock)
[![Go Report Card](https://goreportcard.com/badge/go.nhat.io/grpcmock)](https://goreportcard.com/report/go.nhat.io/grpcmock)
[![GoDevDoc](https://img.shields.io/badge/dev-doc-00ADD8?logo=go)](https://pkg.go.dev/go.nhat.io/grpcmock)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](http://donate.nhat.me)Test gRPC service and client like a pro.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Install](#install)
- [Usage](#usage)
- [Mock a gRPC server](#mock-a-grpc-server)
- [Unary Method](#unary-method)
- [Client-Stream Method](#client-stream-method)
- [Server-Stream Method](#server-stream-method)
- [Bidirectional-Stream Method](#bidirectional-stream-method)
- [Invoke a gRPC method](#invoke-a-grpc-method)
- [Unary Method](#unary-method-1)
- [Client-Stream Method](#client-stream-method-1)
- [Server-Stream Method](#server-stream-method-1)
- [Bidirectional-Stream Method](#bidirectional-stream-method-1)## Prerequisites
- `Go >= 1.21`
[[table of contents]](#table-of-contents)
## Install
```bash
go get go.nhat.io/grpcmock
```[[table of contents]](#table-of-contents)
## Usage
### Mock a gRPC server
Read more about [mocking a gRPC server](resources/docs/SERVER.md)
[[table of contents]](#table-of-contents)
#### Unary Method
Read more about [mocking a Unary Method](resources/docs/SERVER.md#mock-a-unary-method)
```go
package mainimport (
"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)
}
```[[table of contents]](#table-of-contents)
#### Client-Stream Method
Read more about [mocking a Client-Stream Method](resources/docs/SERVER.md#mock-a-client-stream-method)
```go
package mainimport (
"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)
}
```[[table of contents]](#table-of-contents)
#### Server-Stream Method
Read more about [mocking a Server-Stream Method](resources/docs/SERVER.md#mock-a-server-stream-method)
```go
package mainimport (
"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])
}
}
```[[table of contents]](#table-of-contents)
#### Bidirectional-Stream Method
Read more about [mocking a Bidirectional-Stream Method](resources/docs/SERVER.md#mock-a-bidirectional-stream-method)
```go
package mainimport (
"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])
}
}
```[[table of contents]](#table-of-contents)
### Invoke a gRPC method
#### Unary Method
```go
package mainimport (
"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
}
```[[table of contents]](#table-of-contents)
#### Client-Stream Method
```go
package mainimport (
"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
```go
package mainimport (
"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
}
```[[table of contents]](#table-of-contents)
#### Server-Stream Method
```go
package mainimport (
"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
```go
package mainimport (
"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
}
```[[table of contents]](#table-of-contents)
#### Bidirectional-Stream Method
```go
package mainimport (
"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
```go
package mainimport (
"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
}
```[[table of contents]](#table-of-contents)
## Donation
If this project help you reduce time to develop, you can give me a cup of coffee :)
[[table of contents]](#table-of-contents)
### Paypal donation
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](http://donate.nhat.me)
or scan this
[[table of contents]](#table-of-contents)