Categorygo.nhat.io/grpcmock
repositorypackage
0.27.0
Repository: https://github.com/nhatthm/grpcmock.git
Documentation: pkg.go.dev

# 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 to go.nhat.io/grpcmock. v0.19.0 is the last version with github.com/nhatthm/grpcmock.

gRPC Test Utilities for Golang

GitHub Releases Build Status codecov Go Report Card GoDevDoc Donate

Test gRPC service and client like a pro.

Table of Contents

Prerequisites

  • Go >= 1.21

[table of contents]

Install

go get go.nhat.io/grpcmock

[table of contents]

Usage

Mock a gRPC server

Read more about mocking a gRPC server

[table of contents]

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)
}

[table of contents]

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)
}

[table of contents]

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])
	}
}

[table of contents]

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])
	}
}

[table of contents]

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
}

[table of contents]

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
}

[table of contents]

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
}

[table of contents]

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
}

[table of contents]

Donation

If this project help you reduce time to develop, you can give me a cup of coffee :)

[table of contents]

Paypal donation

paypal

       or scan this

[table of contents]