grpcmock

package module
v0.23.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 8, 2023 License: MIT Imports: 40 Imported by: 1

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.17

[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]

Documentation

Overview

Package grpcmock provides functionalities for testing grpc client and server.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func FindServerMethod

func FindServerMethod(srv *Server, method string) *service.Method

FindServerMethod finds a method in the given server.

func InvokeBidirectionalStream

func InvokeBidirectionalStream(
	ctx context.Context,
	method string,
	handle ClientStreamHandler,
	opts ...InvokeOption,
) error

InvokeBidirectionalStream invokes a bidirectional-stream method.

func InvokeClientStream

func InvokeClientStream(
	ctx context.Context,
	method string,
	handle ClientStreamHandler,
	out interface{},
	opts ...InvokeOption,
) error

InvokeClientStream invokes a client-stream method.

func InvokeServerStream

func InvokeServerStream(
	ctx context.Context,
	method string,
	in interface{},
	handle ClientStreamHandler,
	opts ...InvokeOption,
) error

InvokeServerStream invokes a server-stream method.

func InvokeUnary

func InvokeUnary(
	ctx context.Context,
	method string,
	in interface{},
	out interface{},
	opts ...InvokeOption,
) error

InvokeUnary invokes a unary method.

func MatchClientStreamMsgCount

func MatchClientStreamMsgCount(expected int) func() (string, matcher.MatchFn)

MatchClientStreamMsgCount matches a number of messages.

Types

type BidirectionalStreamExpectation added in v0.22.0

type BidirectionalStreamExpectation interface {
	// WithHeader sets an expected header of the given request.
	//
	//	Server.ExpectBidirectionalStream("grpctest.Service/TransformItems").
	//		WithHeader("Locale", "en-US")
	//
	// See: BidirectionalStreamExpectation.WithHeaders().
	WithHeader(header string, value interface{}) BidirectionalStreamExpectation
	// WithHeaders sets a list of expected headers of the given request.
	//
	//	Server.ExpectBidirectionalStream("grpctest.Service/TransformItems").
	//		WithHeaders(map[string]interface{}{"Locale": "en-US"})
	//
	// See: BidirectionalStreamExpectation.WithHeader().
	WithHeaders(headers map[string]interface{}) BidirectionalStreamExpectation

	// ReturnCode sets the response code.
	//
	//	Server.ExpectBidirectionalStream("grpc.Service/TransformItems").
	//		ReturnCode(codes.OK)
	//
	// See: BidirectionalStreamExpectation.ReturnErrorMessage(), BidirectionalStreamExpectation.ReturnError(), BidirectionalStreamExpectation.ReturnErrorf().
	ReturnCode(code codes.Code)
	// ReturnErrorMessage sets the response error message.
	//
	//	Server.ExpectBidirectionalStream("grpc.Service/TransformItems").
	//		ReturnErrorMessage("Internal Server Error")
	//
	// See: BidirectionalStreamExpectation.ReturnCode(), BidirectionalStreamExpectation.ReturnError(), BidirectionalStreamExpectation.ReturnErrorf().
	ReturnErrorMessage(msg string)
	// ReturnError sets the response error.
	//
	//	Server.ExpectBidirectionalStream("grpc.Service/TransformItems").
	//		ReturnError(codes.Internal, "Internal Server Error")
	//
	// See: BidirectionalStreamExpectation.ReturnCode(), BidirectionalStreamExpectation.ReturnErrorMessage(), BidirectionalStreamExpectation.ReturnErrorf().
	ReturnError(code codes.Code, msg string)
	// ReturnErrorf sets the response error.
	//
	//	Server.ExpectBidirectionalStream("grpc.Service/TransformItems").
	//		ReturnErrorf(codes.NotFound, "Item %d not found", 42)
	//
	// See: BidirectionalStreamExpectation.ReturnCode(), BidirectionalStreamExpectation.ReturnErrorMessage(), BidirectionalStreamExpectation.ReturnError().
	ReturnErrorf(code codes.Code, format string, args ...interface{})

	// Run sets a custom handler to handle the given request.
	//
	//	Server.ExpectBidirectionalStream("grpc.Service/TransformItems").
	//		Run(func(context.Context, grpc.ServerStream) error {
	//			return nil
	//		})
	Run(handler func(ctx context.Context, s grpc.ServerStream) error)

	// Once indicates that the mock should only return the value once.
	//
	//	Server.ExpectBidirectionalStream("grpctest.Service/TransformItems").
	//		Once().
	//		Run(func(context.Context, grpc.ServerStream) error {
	//			return nil
	//		})
	//
	// See: BidirectionalStreamExpectation.Twice(), BidirectionalStreamExpectation.UnlimitedTimes(), BidirectionalStreamExpectation.Times().
	Once() BidirectionalStreamExpectation
	// Twice indicates that the mock should only return the value twice.
	//
	//	Server.ExpectBidirectionalStream("grpctest.Service/TransformItems").
	//		Twice().
	//		Run(func(context.Context, grpc.ServerStream) error {
	//			return nil
	//		})
	//
	// See: BidirectionalStreamExpectation.Once(), BidirectionalStreamExpectation.UnlimitedTimes(), BidirectionalStreamExpectation.Times().
	Twice() BidirectionalStreamExpectation
	// UnlimitedTimes indicates that the mock should return the value at least once and there is no max limit in the number
	// of return.
	//
	//	Server.ExpectBidirectionalStream("grpctest.Service/TransformItems").
	//		UnlimitedTimes().
	//		Run(func(context.Context, grpc.ServerStream) error {
	//			return nil
	//		})
	//
	// See: BidirectionalStreamExpectation.Once(), BidirectionalStreamExpectation.Twice(), BidirectionalStreamExpectation.Times().
	UnlimitedTimes() BidirectionalStreamExpectation
	// Times indicates that the mock should only return the indicated number of times.
	//
	//	Server.ExpectBidirectionalStream("grpctest.Service/TransformItems").
	//		Times(5).
	//		Run(func(context.Context, grpc.ServerStream) error {
	//			return nil
	//		})
	//
	// See: BidirectionalStreamExpectation.Once(), BidirectionalStreamExpectation.Twice(), BidirectionalStreamExpectation.UnlimitedTimes().
	Times(i uint) BidirectionalStreamExpectation
	// WaitUntil sets the channel that will block the mocked return until its closed
	// or a message is received.
	//
	//	Server.ExpectBidirectionalStream("grpctest.Service/TransformItems").
	//		WaitUntil(time.After(time.Second)).
	//		Run(func(context.Context, grpc.ServerStream) error {
	//			return nil
	//		})
	//
	// See: BidirectionalStreamExpectation.After()
	WaitUntil(w <-chan time.Time) BidirectionalStreamExpectation
	// After sets how long to block until the call returns.
	//
	//	Server.ExpectBidirectionalStream("grpctest.Service/TransformItems").
	//		After(time.Second).
	//		Run(func(context.Context, grpc.ServerStream) error {
	//			return nil
	//		})
	//
	// See: BidirectionalStreamExpectation.WaitUntil()
	After(d time.Duration) BidirectionalStreamExpectation
}

BidirectionalStreamExpectation represents the expectation for a client-stream request.

nolint: interfacebloat

type ClientStreamExpectation added in v0.22.0

type ClientStreamExpectation interface {
	// WithHeader sets an expected header of the given request.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		WithHeader("Locale", "en-US")
	//
	// See: ClientStreamExpectation.WithHeaders().
	WithHeader(header string, value interface{}) ClientStreamExpectation
	// WithHeaders sets a list of expected headers of the given request.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		WithHeaders(map[string]interface{}{"Locale": "en-US"})
	//
	// See: ClientStreamExpectation.WithHeader().
	WithHeaders(headers map[string]interface{}) ClientStreamExpectation
	// WithPayload sets the expected payload of the given request. It could be a JSON []byte, JSON string, an object (that will be marshaled),
	// or a custom matcher.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		WithPayload(`[{"name": "Foobar"}]`)
	//
	// See: ClientStreamExpectation.WithPayloadf().
	WithPayload(in interface{}) ClientStreamExpectation
	// WithPayloadf formats according to a format specifier and use it as the expected payload of the given request.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		WithPayloadf(`[{"name": %q}]`, "Foobar")
	//
	// See: ClientStreamExpectation.WithPayload().
	WithPayloadf(format string, args ...interface{}) ClientStreamExpectation

	// ReturnCode sets the response code.
	//
	//	Server.ExpectClientStream("grpc.Service/CreateItems").
	//		ReturnCode(codes.OK)
	//
	// See: ClientStreamExpectation.ReturnErrorMessage(), ClientStreamExpectation.ReturnError(), ClientStreamExpectation.ReturnErrorf().
	ReturnCode(code codes.Code)
	// ReturnErrorMessage sets the response error message.
	//
	//	Server.ExpectClientStream("grpc.Service/CreateItems").
	//		ReturnErrorMessage("Internal Server Error")
	//
	// See: ClientStreamExpectation.ReturnCode(), ClientStreamExpectation.ReturnError(), ClientStreamExpectation.ReturnErrorf().
	ReturnErrorMessage(msg string)
	// ReturnError sets the response error.
	//
	//	Server.ExpectClientStream("grpc.Service/CreateItems").
	//		ReturnError(codes.Internal, "Internal Server Error")
	//
	// See: ClientStreamExpectation.ReturnCode(), ClientStreamExpectation.ReturnErrorMessage(), ClientStreamExpectation.ReturnErrorf().
	ReturnError(code codes.Code, msg string)
	// ReturnErrorf sets the response error.
	//
	//	Server.ExpectClientStream("grpc.Service/CreateItems").
	//		ReturnErrorf(codes.NotFound, "Item %d not found", 42)
	//
	// See: ClientStreamExpectation.ReturnCode(), ClientStreamExpectation.ReturnErrorMessage(), ClientStreamExpectation.ReturnError().
	ReturnErrorf(code codes.Code, format string, args ...interface{})
	// Return sets the result to return to client.
	//
	//	Server.ExpectClientStream("grpc.Service/CreateItems").
	//		Return(`{"num_items": 1}`)
	//
	// See: ClientStreamExpectation.Returnf(), ClientStreamExpectation.ReturnJSON(), ClientStreamExpectation.ReturnFile().
	Return(v interface{})
	// Returnf formats according to a format specifier and use it as the result to return to client.
	//
	//	Server.ExpectClientStream("grpc.Service/CreateItems").
	//		Returnf(`{"num_items": %d}`, 1)
	//
	// See: ClientStreamExpectation.Return(), ClientStreamExpectation.ReturnJSON(), ClientStreamExpectation.ReturnFile().
	Returnf(format string, args ...interface{})

	// ReturnJSON marshals the object using json.Marshal and uses it as the result to return to client.
	//
	//	Server.ExpectClientStream("grpc.Service/CreateItems").
	//		ReturnJSON(map[string]interface{}{"num_items": 1})
	//
	// See: ClientStreamExpectation.Return(), ClientStreamExpectation.Returnf(), ClientStreamExpectation.ReturnFile().
	ReturnJSON(v interface{})
	// ReturnFile reads the file and uses its content as the result to return to client.
	//
	//	Server.ExpectUnary("grpctest.Service/CreateItems").
	//		ReturnFile("resources/fixtures/response.json")
	//
	// See: ClientStreamExpectation.Return(), ClientStreamExpectation.Returnf(), ClientStreamExpectation.ReturnJSON().
	ReturnFile(filePath string)

	// Run sets a custom handler to handle the given request.
	//
	//	   Server.ExpectClientStream("grpc.Service/CreateItems").
	//			Run(func(context.Context, grpc.ServerStreamer) (interface{}, error) {
	//				return &grpctest.CreateItemsResponse{NumItems: 1}, nil
	//			})
	Run(handler func(ctx context.Context, s grpc.ServerStream) (interface{}, error))

	// Once indicates that the mock should only return the value once.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		Return(`{"num_items": 1}`)
	//		Once()
	//
	// See: ClientStreamExpectation.Twice(), ClientStreamExpectation.UnlimitedTimes(), ClientStreamExpectation.Times().
	Once() ClientStreamExpectation
	// Twice indicates that the mock should only return the value twice.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		Return(`{"num_items": 1}`)
	//		Twice()
	//
	// See: ClientStreamExpectation.Once(), ClientStreamExpectation.UnlimitedTimes(), ClientStreamExpectation.Times().
	Twice() ClientStreamExpectation
	// UnlimitedTimes indicates that the mock should return the value at least once and there is no max limit in the number
	// of return.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		Return(`{"num_items": 1}`)
	//		UnlimitedTimes()
	//
	// See: ClientStreamExpectation.Once(), ClientStreamExpectation.Twice(), ClientStreamExpectation.Times().
	UnlimitedTimes() ClientStreamExpectation
	// Times indicates that the mock should only return the indicated number of times.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		Return(`{"num_items": 1}`)
	//		Times(5)
	//
	// See: ClientStreamExpectation.Once(), ClientStreamExpectation.Twice(), ClientStreamExpectation.UnlimitedTimes().
	Times(i uint) ClientStreamExpectation
	// WaitUntil sets the channel that will block the mocked return until its closed
	// or a message is received.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		WaitUntil(time.After(time.Second)).
	//		Return(`{"num_items": 1}`)
	//
	// See: ClientStreamExpectation.After().
	WaitUntil(w <-chan time.Time) ClientStreamExpectation
	// After sets how long to block until the call returns.
	//
	//	Server.ExpectClientStream("grpctest.Service/CreateItems").
	//		After(time.Second).
	//		Return(`{"num_items": 1}`)
	//
	// See: ClientStreamExpectation.WaitUntil().
	After(d time.Duration) ClientStreamExpectation
}

ClientStreamExpectation represents the expectation for a client-stream request.

nolint: interfacebloat

type ClientStreamHandler

type ClientStreamHandler func(s grpc.ClientStream) error

ClientStreamHandler handles a client stream.

func RecvAll

func RecvAll(out interface{}) ClientStreamHandler

RecvAll reads everything from the stream and put into the output.

func SendAll

func SendAll(in interface{}) ClientStreamHandler

SendAll sends everything to the stream.

func SendAndRecvAll

func SendAndRecvAll(in interface{}, out interface{}) ClientStreamHandler

SendAndRecvAll sends and receives messages to and from grpc server in turn until server sends the io.EOF.

func (ClientStreamHandler) Handle

Handle handles a client stream.

type ContextDialer

type ContextDialer = func(context.Context, string) (net.Conn, error)

ContextDialer is to set up the dialer.

type InvokeOption

type InvokeOption func(c *invokeConfig)

InvokeOption sets invoker config.

func WithBufConnDialer

func WithBufConnDialer(l *bufconn.Listener) InvokeOption

WithBufConnDialer sets a *bufconn.Listener as the context dialer.

See:

  • grpcmock.WithContextDialer()

func WithCallOptions

func WithCallOptions(opts ...grpc.CallOption) InvokeOption

WithCallOptions sets call options.

func WithContextDialer

func WithContextDialer(d ContextDialer) InvokeOption

WithContextDialer sets a context dialer to create connections.

See:

  • grpcmock.WithBufConnDialer()

func WithDialOptions

func WithDialOptions(opts ...grpc.DialOption) InvokeOption

WithDialOptions sets dial options.

func WithHeader

func WithHeader(key, value string) InvokeOption

WithHeader sets request header.

func WithHeaders

func WithHeaders(header map[string]string) InvokeOption

WithHeaders sets request header.

func WithInsecure

func WithInsecure() InvokeOption

WithInsecure disables transport security for the connections.

type Server

type Server struct {

	// Holds the requested that were made to this server.
	Requests []planner.Expectation
	// contains filtered or unexported fields
}

Server wraps a grpc server and provides mocking functionalities.

Example (FirstMatch_planner)
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"math/rand"
	"sync"

	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/planner"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithPlanner(planner.FirstMatch()),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectUnary("grpctest.ItemService/GetItem").
				WithPayload(&grpctest.GetItemRequest{Id: 1}).
				Return(&grpctest.Item{Id: 1, Name: "FoodUniversity"})

			s.ExpectUnary("grpctest.ItemService/GetItem").
				WithPayload(&grpctest.GetItemRequest{Id: 2}).
				Return(&grpctest.Item{Id: 2, Name: "Metaverse"})

			s.ExpectUnary("grpctest.ItemService/GetItem").
				WithPayload(&grpctest.GetItemRequest{Id: 3}).
				Return(&grpctest.Item{Id: 3, Name: "Crypto"})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	ids := []int32{1, 2, 3}
	result := make([]*grpctest.Item, len(ids))

	rand.Shuffle(len(ids), func(i, j int) {
		ids[i], ids[j] = ids[j], ids[i]
	})

	var wg sync.WaitGroup

	for _, id := range ids {
		wg.Add(1)

		go func(id int32) {
			defer wg.Done()

			out := &grpctest.Item{}

			err := grpcmock.InvokeUnary(context.Background(),
				"grpctest.ItemService/GetItem", &grpctest.GetItemRequest{Id: id}, out,
				grpcmock.WithInsecure(),
				grpcmock.WithBufConnDialer(buf),
			)
			must.NotFail(err)

			result[id-1] = out
		}(id)
	}

	wg.Wait()

	output, err := json.MarshalIndent(result, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

[
    {
        "id": 1,
        "name": "FoodUniversity"
    },
    {
        "id": 2,
        "name": "Metaverse"
    },
    {
        "id": 3,
        "name": "Crypto"
    }
]

func NewServer

func NewServer(opts ...ServerOption) *Server

NewServer creates mocked server.

Example (BidirectionalStreamMethod)
package main

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"google.golang.org/grpc"
	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectBidirectionalStream("grpctest.ItemService/TransformItems").
				Run(func(ctx context.Context, s grpc.ServerStream) error {
					for {
						item := &grpctest.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
						}
					}
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	in := []*grpctest.Item{
		{Id: 40, Name: "Item #40"},
		{Id: 41, Name: "Item #41"},
		{Id: 42, Name: "Item #42"},
	}

	out := make([]*grpctest.Item, 0)

	err := grpcmock.InvokeBidirectionalStream(context.Background(),
		"grpctest.ItemService/TransformItems",
		grpcmock.SendAndRecvAll(in, &out),
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

[
    {
        "id": 40,
        "name": "Modified #40"
    },
    {
        "id": 41,
        "name": "Modified #41"
    },
    {
        "id": 42,
        "name": "Modified #42"
    }
]
Example (ClientStreamMethod)
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectClientStream("grpctest.ItemService/CreateItems").
				WithPayload([]*grpctest.Item{
					{Id: 41, Name: "Item #41"},
					{Id: 42, Name: "Item #42"},
				}).
				Return(&grpctest.CreateItemsResponse{NumItems: 2})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := &grpctest.CreateItemsResponse{}
	err := grpcmock.InvokeClientStream(context.Background(),
		"grpctest.ItemService/CreateItems",
		grpcmock.SendAll([]*grpctest.Item{
			{Id: 41, Name: "Item #41"},
			{Id: 42, Name: "Item #42"},
		}),
		out,
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

{
    "num_items": 2
}
Example (ClientStreamMethod_customHandler)
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"google.golang.org/grpc"
	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/stream"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectClientStream("grpctest.ItemService/CreateItems").
				WithPayload(grpcmock.MatchClientStreamMsgCount(3)).
				Run(func(_ context.Context, s grpc.ServerStream) (interface{}, error) {
					out := make([]*grpctest.Item, 0)

					if err := stream.RecvAll(s, &out); err != nil {
						return nil, err
					}

					cnt := int64(0)

					for _, msg := range out {
						if msg.Id > 40 {
							cnt++
						}
					}

					return &grpctest.CreateItemsResponse{NumItems: cnt}, nil
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := &grpctest.CreateItemsResponse{}
	err := grpcmock.InvokeClientStream(context.Background(),
		"grpctest.ItemService/CreateItems",
		grpcmock.SendAll([]*grpctest.Item{
			{Id: 40, Name: "Item #40"},
			{Id: 41, Name: "Item #41"},
			{Id: 42, Name: "Item #42"},
		}),
		out,
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

{
    "num_items": 2
}
Example (ServerStreamMethod)
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectServerStream("grpctest.ItemService/ListItems").
				Return([]*grpctest.Item{
					{Id: 41, Name: "Item #41"},
					{Id: 42, Name: "Item #42"},
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := make([]*grpctest.Item, 0)
	err := grpcmock.InvokeServerStream(context.Background(),
		"grpctest.ItemService/ListItems",
		&grpctest.ListItemsRequest{},
		grpcmock.RecvAll(&out),
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

[
    {
        "id": 41,
        "name": "Item #41"
    },
    {
        "id": 42,
        "name": "Item #42"
    }
]
Example (ServerStreamMethod_customHandler)
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"google.golang.org/grpc"
	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectServerStream("grpctest.ItemService/ListItems").
				Run(func(_ context.Context, _ interface{}, s grpc.ServerStream) error {
					_ = s.SendMsg(&grpctest.Item{Id: 41, Name: "Item #41"}) // nolint: errcheck
					_ = s.SendMsg(&grpctest.Item{Id: 42, Name: "Item #42"}) // nolint: errcheck

					return nil
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := make([]*grpctest.Item, 0)
	err := grpcmock.InvokeServerStream(context.Background(),
		"grpctest.ItemService/ListItems",
		&grpctest.ListItemsRequest{},
		grpcmock.RecvAll(&out),
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

[
    {
        "id": 41,
        "name": "Item #41"
    },
    {
        "id": 42,
        "name": "Item #42"
    }
]
Example (ServerStreamMethod_customStreamBehaviors)
package main

import (
	"context"
	"fmt"

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectServerStream("grpctest.ItemService/ListItems").
				ReturnStream().
				Send(&grpctest.Item{Id: 41, Name: "Item #41"}).
				ReturnError(codes.Aborted, "server aborted the transaction")
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := make([]*grpctest.Item, 0)
	err := grpcmock.InvokeServerStream(context.Background(),
		"grpctest.ItemService/ListItems",
		&grpctest.ListItemsRequest{},
		grpcmock.RecvAll(&out),
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)

	fmt.Printf("received items: %d\n", len(out))
	fmt.Printf("error: %s", err)

}
Output:

received items: 0
error: rpc error: code = Aborted desc = server aborted the transaction
Example (UnaryMethod)
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectUnary("grpctest.ItemService/GetItem").
				WithPayload(&grpctest.GetItemRequest{Id: 41}).
				Return(&grpctest.Item{
					Id:     41,
					Locale: "en-US",
					Name:   "Item #41",
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := &grpctest.Item{}
	err := grpcmock.InvokeUnary(context.Background(),
		"grpctest.ItemService/GetItem", &grpctest.GetItemRequest{Id: 41}, out,
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

{
    "id": 41,
    "locale": "en-US",
    "name": "Item #41"
}
Example (UnaryMethod_customHandler)
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectUnary("grpctest.ItemService/GetItem").
				WithPayload(&grpctest.GetItemRequest{Id: 42}).
				Run(func(ctx context.Context, in interface{}) (interface{}, error) {
					req := in.(*grpctest.GetItemRequest) // nolint: errcheck

					var locale string

					md, _ := metadata.FromIncomingContext(ctx)
					if md != nil {
						if values := md.Get("locale"); len(values) > 0 {
							locale = values[0]
						}
					}

					return &grpctest.Item{
						Id:     req.Id,
						Locale: locale,
						Name:   fmt.Sprintf("Item #%d", req.Id),
					}, nil
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := &grpctest.Item{}
	err := grpcmock.InvokeUnary(context.Background(),
		"grpctest.ItemService/GetItem", &grpctest.GetItemRequest{Id: 42}, out,
		grpcmock.WithHeader("locale", "en-US"),
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

{
    "id": 42,
    "locale": "en-US",
    "name": "Item #42"
}
Example (WithPort)
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithPort(8080),
		func(s *grpcmock.Server) {
			s.ExpectUnary("grpctest.ItemService/GetItem").
				WithPayload(&grpctest.GetItemRequest{Id: 41}).
				Return(&grpctest.Item{
					Id:     41,
					Locale: "en-US",
					Name:   "Item #41",
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := &grpctest.Item{}
	err := grpcmock.InvokeUnary(context.Background(),
		":8080/grpctest.ItemService/GetItem", &grpctest.GetItemRequest{Id: 41}, out,
		grpcmock.WithInsecure(),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

{
    "id": 41,
    "locale": "en-US",
    "name": "Item #41"
}

func NewUnstartedServer

func NewUnstartedServer(opts ...ServerOption) *Server

NewUnstartedServer returns a new Server but doesn't start it.

func (*Server) Address

func (s *Server) Address() string

Address returns server address.

func (*Server) Close

func (s *Server) Close() error

Close stops and closes all open connections and listeners.

func (*Server) ExpectBidirectionalStream

func (s *Server) ExpectBidirectionalStream(method string) BidirectionalStreamExpectation

ExpectBidirectionalStream adds a new expected bidirectional-stream request.

Server.ExpectBidirectionalStream("grpctest.Service/TransformItems")

func (*Server) ExpectClientStream

func (s *Server) ExpectClientStream(method string) ClientStreamExpectation

ExpectClientStream adds a new expected client-stream request.

Server.ExpectClientStream("grpctest.Service/CreateItems")

func (*Server) ExpectServerStream

func (s *Server) ExpectServerStream(method string) ServerStreamExpectation

ExpectServerStream adds a new expected server-stream request.

Server.ExpectServerStream("grpctest.Service/ListItems")

func (*Server) ExpectUnary

func (s *Server) ExpectUnary(method string) UnaryExpectation

ExpectUnary adds a new expected unary request.

Server.ExpectUnary("grpctest.Service/GetItem")

func (*Server) ExpectationsWereMet

func (s *Server) ExpectationsWereMet() error

ExpectationsWereMet checks whether all queued expectations were met in order. If any of them was not met - an error is returned.

func (*Server) ResetExpectations

func (s *Server) ResetExpectations()

ResetExpectations resets all the expectations.

func (*Server) Serve

func (s *Server) Serve()

Serve runs the grpc server.

func (*Server) WithPlanner

func (s *Server) WithPlanner(p planner.Planner) *Server

WithPlanner sets the planner.

Example
package main

import (
	"context"
	"errors"
	"fmt"

	"github.com/stretchr/testify/mock"
	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	plannerMock "go.nhat.io/grpcmock/mock/planner"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			p := &plannerMock.Planner{}

			p.On("IsEmpty").Return(false)
			p.On("Expect", mock.Anything)
			p.On("Plan", mock.Anything, mock.Anything, mock.Anything).
				Return(nil, errors.New("always fail"))

			s.WithPlanner(p)

			s.ExpectUnary("grpctest.ItemService/GetItem").
				Run(func(context.Context, interface{}) (interface{}, error) {
					panic(`this never happens`)
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	err := grpcmock.InvokeUnary(context.Background(),
		"grpctest.ItemService/GetItem", &grpctest.GetItemRequest{Id: 41}, &grpctest.Item{},
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)

	fmt.Println(err)

}
Output:

rpc error: code = Internal desc = always fail

func (*Server) WithTest

func (s *Server) WithTest(t T) *Server

WithTest sets the *testing.T of the server.

type ServerMocker

type ServerMocker func(t T) *Server

ServerMocker is a constructor to create a new mocked server.

func MockServer

func MockServer(opts ...ServerOption) ServerMocker

MockServer starts a new mocked server and ensures all the expectations were met at the end of the test.

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/stretchr/testify/require"

	"go.nhat.io/grpcmock"
	xassert "go.nhat.io/grpcmock/assert"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	// Simulate a test function.
	//
	// In reality, it's just straightforward:
	//	func TestMockAndStartServer(t *testing.T) {
	//		t.Parallel()
	//
	//		s, d := grpcmock.MockServer()
	//		// Client call and assertions.
	//	}
	TestMockServer := func(t grpcmock.T) {
		srv := grpcmock.MockServer(
			grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
			func(s *grpcmock.Server) {
				s.ExpectUnary("grpctest.ItemService/GetItem").
					WithPayload(&grpctest.GetItemRequest{Id: 41}).
					Return(&grpctest.Item{
						Id:     41,
						Locale: "en-US",
						Name:   "Item #41",
					})
			},
		)(t)

		// Call the service.
		out := &grpctest.Item{}
		method := fmt.Sprintf("%s/grpctest.ItemService/GetItem", srv.Address())
		err := grpcmock.InvokeUnary(context.Background(),
			method, &grpctest.GetItemRequest{Id: 41}, out,
			grpcmock.WithInsecure(),
		)

		expected := &grpctest.Item{
			Id:     41,
			Locale: "en-US",
			Name:   "Item #41",
		}

		require.NoError(t, err)
		xassert.EqualMessage(t, expected, out)

		output, err := json.MarshalIndent(out, "", "    ")
		require.NoError(t, err)

		// Output for the example.
		fmt.Println(string(output))
	}

	TestMockServer(grpcmock.NoOpT())

}
Output:

{
    "id": 41,
    "locale": "en-US",
    "name": "Item #41"
}

func MockUnstartedServer

func MockUnstartedServer(opts ...ServerOption) ServerMocker

MockUnstartedServer mocks the server and ensures all the expectations were met at the end of the test.

type ServerMockerWithContextDialer

type ServerMockerWithContextDialer func(t T) (*Server, ContextDialer)

ServerMockerWithContextDialer starts a new mocked server with a bufconn and returns it as a context dialer for the grpc.DialOption.

func MockServerWithBufConn

func MockServerWithBufConn(opts ...ServerOption) ServerMockerWithContextDialer

MockServerWithBufConn starts a new mocked server with bufconn and ensures all the expectations were met at the end of the test.

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/stretchr/testify/require"

	"go.nhat.io/grpcmock"
	xassert "go.nhat.io/grpcmock/assert"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	// Simulate a test function.
	//
	// In reality, it's just straightforward:
	//	func TestMockAndStartServer(t *testing.T) {
	//		t.Parallel()
	//
	//		s, d := grpcmock.MockServerWithBufConn()
	//		// Client call and assertions.
	//	}
	TestMockServerWithBufConn := func(t grpcmock.T) {
		_, d := grpcmock.MockServerWithBufConn(
			grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
			func(s *grpcmock.Server) {
				s.ExpectUnary("grpctest.ItemService/GetItem").
					WithPayload(&grpctest.GetItemRequest{Id: 41}).
					Return(&grpctest.Item{
						Id:     41,
						Locale: "en-US",
						Name:   "Item #41",
					})
			},
		)(t)

		// Call the service.
		out := &grpctest.Item{}
		err := grpcmock.InvokeUnary(context.Background(),
			"grpctest.ItemService/GetItem", &grpctest.GetItemRequest{Id: 41}, out,
			grpcmock.WithInsecure(),
			grpcmock.WithContextDialer(d),
		)

		expected := &grpctest.Item{
			Id:     41,
			Locale: "en-US",
			Name:   "Item #41",
		}

		require.NoError(t, err)
		xassert.EqualMessage(t, expected, out)

		output, err := json.MarshalIndent(out, "", "    ")
		require.NoError(t, err)

		// Output for the example.
		fmt.Println(string(output))
	}

	TestMockServerWithBufConn(grpcmock.NoOpT())

}
Output:

{
    "id": 41,
    "locale": "en-US",
    "name": "Item #41"
}

type ServerOption

type ServerOption func(s *Server)

ServerOption sets up the mocked server.

func ChainStreamInterceptor

func ChainStreamInterceptor(interceptors ...grpc.StreamServerInterceptor) ServerOption

ChainStreamInterceptor is a wrapper of google.golang.org/grpc.ChainStreamInterceptor().

func ChainUnaryInterceptor

func ChainUnaryInterceptor(interceptors ...grpc.UnaryServerInterceptor) ServerOption

ChainUnaryInterceptor is a wrapper of google.golang.org/grpc.ChainUnaryInterceptor().

func ConnectionTimeout

func ConnectionTimeout(d time.Duration) ServerOption

ConnectionTimeout is a wrapper of google.golang.org/grpc.ConnectionTimeout().

func Creds

Creds is a wrapper of google.golang.org/grpc.Creds().

func InTapHandle

func InTapHandle(h tap.ServerInHandle) ServerOption

InTapHandle is a wrapper of google.golang.org/grpc.InTapHandle().

func InitialConnWindowSize

func InitialConnWindowSize(sz int32) ServerOption

InitialConnWindowSize is a wrapper of google.golang.org/grpc.InitialConnWindowSize().

func InitialWindowSize

func InitialWindowSize(sz int32) ServerOption

InitialWindowSize is a wrapper of google.golang.org/grpc.InitialWindowSize().

func KeepaliveEnforcementPolicy

func KeepaliveEnforcementPolicy(kep keepalive.EnforcementPolicy) ServerOption

KeepaliveEnforcementPolicy is a wrapper of google.golang.org/grpc.KeepaliveEnforcementPolicy().

func KeepaliveParams

func KeepaliveParams(kp keepalive.ServerParameters) ServerOption

KeepaliveParams is a wrapper of google.golang.org/grpc.KeepaliveParams().

func MaxConcurrentStreams

func MaxConcurrentStreams(n uint32) ServerOption

MaxConcurrentStreams is a wrapper of google.golang.org/grpc.MaxConcurrentStreams().

func MaxHeaderListSize

func MaxHeaderListSize(sz uint32) ServerOption

MaxHeaderListSize is a wrapper of google.golang.org/grpc.MaxHeaderListSize().

func MaxRecvMsgSize

func MaxRecvMsgSize(m int) ServerOption

MaxRecvMsgSize is a wrapper of google.golang.org/grpc.MaxRecvMsgSize().

func MaxSendMsgSize

func MaxSendMsgSize(m int) ServerOption

MaxSendMsgSize is a wrapper of google.golang.org/grpc.MaxSendMsgSize().

func ReadBufferSize

func ReadBufferSize(sz int) ServerOption

ReadBufferSize is a wrapper of google.golang.org/grpc.ReadBufferSize().

func RegisterService

func RegisterService(registerFunc interface{}) ServerOption

RegisterService registers a new service using the generated register function.

grpcmock.MockUnstartedServer(
	grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
	func(s *grpcmock.Server) {
		s.ExpectUnary("grpctest.ItemService/GetItem").UnlimitedTimes().
			Return(&grpctest.Item{})
	},
)(t)

See: RegisterServiceFromInstance(), RegisterServiceFromMethods().

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectUnary("grpctest.ItemService/GetItem").
				WithPayload(&grpctest.GetItemRequest{Id: 41}).
				Return(&grpctest.Item{
					Id:     41,
					Locale: "en-US",
					Name:   "Item #41",
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := &grpctest.Item{}
	err := grpcmock.InvokeUnary(context.Background(),
		"grpctest.ItemService/GetItem", &grpctest.GetItemRequest{Id: 41}, out,
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

{
    "id": 41,
    "locale": "en-US",
    "name": "Item #41"
}

func RegisterServiceFromInstance

func RegisterServiceFromInstance(id string, svc interface{}) ServerOption

RegisterServiceFromInstance registers a new service using the generated server interface.

grpcmock.MockUnstartedServer(
	grpcmock.RegisterServiceFromInstance("grpctest.ItemService", (*grpctest.ItemServiceServer)(nil)),
	func(s *grpcmock.Server) {
		s.ExpectUnary("grpctest.ItemService/GetItem").UnlimitedTimes().
			Return(&grpctest.Item{})
	},
)(t)

See: RegisterService(), RegisterServiceFromMethods().

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterServiceFromInstance("grpctest.ItemService", (*grpctest.ItemServiceServer)(nil)),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectUnary("grpctest.ItemService/GetItem").
				WithPayload(&grpctest.GetItemRequest{Id: 41}).
				Return(&grpctest.Item{
					Id:     41,
					Locale: "en-US",
					Name:   "Item #41",
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := &grpctest.Item{}
	err := grpcmock.InvokeUnary(context.Background(),
		"grpctest.ItemService/GetItem", &grpctest.GetItemRequest{Id: 41}, out,
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

{
    "id": 41,
    "locale": "en-US",
    "name": "Item #41"
}

func RegisterServiceFromMethods

func RegisterServiceFromMethods(serviceMethods ...service.Method) ServerOption

RegisterServiceFromMethods registers a new service using service.Method definition.

   grpcmock.MockUnstartedServer(
   	grpcmock.RegisterServiceFromMethods(service.Method{
			ServiceName: "grpctest.ItemService",
			MethodName:  "GetItem",
			MethodType:  service.TypeUnary,
			Input:       &grpctest.GetItemRequest{},
			Output:      &grpctest.Item{},
   	}),
   	func(s *grpcmock.Server) {
   		s.ExpectUnary("grpctest.ItemService/GetItem").UnlimitedTimes().
   			Return(&grpctest.Item{})
   	},
   )(t)

See: RegisterService(), RegisterServiceFromInstance().

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"

	"google.golang.org/grpc/test/bufconn"

	"go.nhat.io/grpcmock"
	"go.nhat.io/grpcmock/must"
	"go.nhat.io/grpcmock/service"
	"go.nhat.io/grpcmock/test/grpctest"
)

func main() {
	buf := bufconn.Listen(1024 * 1024)
	defer buf.Close() // nolint: errcheck

	srv := grpcmock.NewServer(
		grpcmock.RegisterServiceFromMethods(service.Method{
			ServiceName: "grpctest.ItemService",
			MethodName:  "GetItem",
			MethodType:  service.TypeUnary,
			Input:       &grpctest.GetItemRequest{},
			Output:      &grpctest.Item{},
		}),
		grpcmock.WithListener(buf),
		func(s *grpcmock.Server) {
			s.ExpectUnary("grpctest.ItemService/GetItem").
				WithPayload(&grpctest.GetItemRequest{Id: 41}).
				Return(&grpctest.Item{
					Id:     41,
					Locale: "en-US",
					Name:   "Item #41",
				})
		},
	)

	defer srv.Close() // nolint: errcheck

	// Call the service.
	out := &grpctest.Item{}
	err := grpcmock.InvokeUnary(context.Background(),
		"grpctest.ItemService/GetItem", &grpctest.GetItemRequest{Id: 41}, out,
		grpcmock.WithInsecure(),
		grpcmock.WithBufConnDialer(buf),
	)
	must.NotFail(err)

	output, err := json.MarshalIndent(out, "", "    ")
	must.NotFail(err)

	fmt.Println(string(output))

}
Output:

{
    "id": 41,
    "locale": "en-US",
    "name": "Item #41"
}

func StatsHandler

func StatsHandler(h stats.Handler) ServerOption

StatsHandler is a wrapper of google.golang.org/grpc.StatsHandler().

func StreamInterceptor

func StreamInterceptor(i grpc.StreamServerInterceptor) ServerOption

StreamInterceptor is a wrapper of google.golang.org/grpc.ChainStreamInterceptor().

func UnaryInterceptor

func UnaryInterceptor(i grpc.UnaryServerInterceptor) ServerOption

UnaryInterceptor is a wrapper of google.golang.org/grpc.ChainUnaryInterceptor().

func UnknownServiceHandler

func UnknownServiceHandler(streamHandler grpc.StreamHandler) ServerOption

UnknownServiceHandler is a wrapper of google.golang.org/grpc.UnknownServiceHandler().

func WithAddress

func WithAddress(addr string) ServerOption

WithAddress sets server address.

func WithListener

func WithListener(l net.Listener) ServerOption

WithListener sets the listener. Server does not need to start a new one.

func WithPlanner

func WithPlanner(p planner.Planner) ServerOption

WithPlanner sets the expectations' planner.

grpcmock.MockServer(
	grpcmock.RegisterService(grpctest.RegisterItemServiceServer),
	grpcmock.WithPlanner(planner.FirstMatch()),
	func(s *grpcmock.Server) {
		s.ExpectUnary("grpctest.ItemService/GetItem").UnlimitedTimes().
			Return(&grpctest.Item{})
	},
)(t)

func WithPort

func WithPort(port int) ServerOption

WithPort sets server address port.

func WriteBufferSize

func WriteBufferSize(sz int) ServerOption

WriteBufferSize is a wrapper of google.golang.org/grpc.WriteBufferSize().

type ServerStreamExpectation added in v0.22.0

type ServerStreamExpectation interface {
	// WithHeader sets an expected header of the given request.
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		WithHeader("Locale", "en-US")
	//
	// See: ServerStreamExpectation.WithHeaders().
	WithHeader(header string, value interface{}) ServerStreamExpectation
	// WithHeaders sets a list of expected headers of the given request.
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		WithHeaders(map[string]interface{}{"Locale": "en-US"})
	//
	// See: ServerStreamExpectation.WithHeader().
	WithHeaders(headers map[string]interface{}) ServerStreamExpectation
	// WithPayload sets the expected payload of the given request. It could be a JSON []byte, JSON string, or a slice of objects (that will be marshaled).
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		WithPayload(`{"message": "hello world!"}`)
	//
	// See: ServerStreamExpectation.WithPayloadf().
	WithPayload(in interface{}) ServerStreamExpectation
	// WithPayloadf formats according to a format specifier and use it as the expected payload of the given request.
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		WithPayloadf(`{"message": "hello %s"}`, "john")
	//
	// See: ServerStreamExpectation.WithPayload().
	WithPayloadf(format string, args ...interface{}) ServerStreamExpectation

	// ReturnCode sets the response code.
	//
	//	Server.ExpectServerStream("grpc.Service/ListItems").
	//		ReturnCode(codes.OK)
	//
	// See: ServerStreamExpectation.ReturnErrorMessage(), ServerStreamExpectation.ReturnError(), ServerStreamExpectation.ReturnErrorf().
	ReturnCode(code codes.Code)
	// ReturnErrorMessage sets the response error message.
	//
	//	Server.ExpectServerStream("grpc.Service/ListItems").
	//		ReturnErrorMessage("Internal Server Error")
	//
	// See: ServerStreamExpectation.ReturnCode(), ServerStreamExpectation.ReturnError(), ServerStreamExpectation.ReturnErrorf().
	ReturnErrorMessage(msg string)
	// ReturnError sets the response error.
	//
	//	Server.ExpectServerStream("grpc.Service/ListItems").
	//		ReturnError(codes.Internal, "Internal Server Error")
	//
	// See: ServerStreamExpectation.ReturnCode(), ServerStreamExpectation.ReturnErrorMessage(), ServerStreamExpectation.ReturnErrorf().
	ReturnError(code codes.Code, msg string)
	// ReturnErrorf sets the response error.
	//
	//	Server.ExpectServerStream("grpc.Service/ListItems").
	//		ReturnErrorf(codes.NotFound, "Item %d not found", 42)
	//
	// See: ServerStreamExpectation.ReturnCode(), ServerStreamExpectation.ReturnErrorMessage(), ServerStreamExpectation.ReturnError().
	ReturnErrorf(code codes.Code, format string, args ...interface{})
	// Return sets the result to return to client.
	//
	//	Server.ExpectServerStream("grpc.Service/ListItems").
	//		Return(`[{"id": 42}]`)
	//
	// See: ServerStreamExpectation.Returnf(), ServerStreamExpectation.ReturnJSON(), ServerStreamExpectation.ReturnFile(), ServerStreamExpectation.ReturnStream().
	Return(v interface{})
	// Returnf formats according to a format specifier and use it as the result to return to client.
	//
	//	Server.ExpectServerStream("grpc.Service/ListItems").
	//		Returnf(`[{"id": %d}]`, 42)
	//
	// See: ServerStreamExpectation.Return(), ServerStreamExpectation.ReturnJSON(), ServerStreamExpectation.ReturnFile(), ServerStreamExpectation.ReturnStream().
	Returnf(format string, args ...interface{})
	// ReturnJSON marshals the object using json.Marshal and uses it as the result to return to client.
	//
	//	Server.ExpectServerStream("grpc.Service/ListItems").
	//		ReturnJSON([]map[string]string{{"foo": "bar"}})
	//
	// See: ServerStreamExpectation.Return(), ServerStreamExpectation.Returnf(), ServerStreamExpectation.ReturnFile(), ServerStreamExpectation.ReturnStream().
	ReturnJSON(v interface{})
	// ReturnFile reads the file and uses its content as the result to return to client.
	//
	//	Server.ExpectServerStream("grpc.Service/ListItems").
	//		ReturnFile("resources/fixtures/response.json")
	//
	// See: ServerStreamExpectation.Return(), ServerStreamExpectation.Returnf(), ServerStreamExpectation.ReturnJSON(), ServerStreamExpectation.ReturnStream().
	ReturnFile(filePath string)
	// ReturnStream returns the stream with custom behaviors.
	//
	//	   Server.ExpectServerStream("grpc.Service/ListItems").
	//	   	ReturnStream().
	//	   	Send(grpctest.Item{
	//				Id:     42,
	//				Locale: "en-US",
	//		 		Name:   "Foobar",
	//			}).
	//			ReturnError(codes.Internal, "stream error")
	//
	// See: ServerStreamExpectation.Return(), ServerStreamExpectation.Returnf(), ServerStreamExpectation.ReturnJSON(), ServerStreamExpectation.ReturnFile().
	ReturnStream() ServerStreamHandler
	// Run sets a custom handler to handle the given request.
	//
	//	   Server.ExpectServerStream("grpc.Service/ListItems").
	//			Run(func(ctx context.Context, in interface{}, srv interface{}) error {
	//				srv := out.(grpc.ServerStreamer)
	//
	//				return srv.SendMsg(grpctest.Item{Id: 42})
	//			})
	Run(handler func(ctx context.Context, in interface{}, s grpc.ServerStream) error)

	// Once indicates that the mock should only return the value once.
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		Return(`[{"id": 42}]`)
	//		Once()
	//
	// See: ServerStreamExpectation.Twice(), ServerStreamExpectation.UnlimitedTimes(), ServerStreamExpectation.Times().
	Once() ServerStreamExpectation
	// Twice indicates that the mock should only return the value twice.
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		Return(`[{"id": 42}]`)
	//		Twice()
	//
	// See: ServerStreamExpectation.Once(), ServerStreamExpectation.UnlimitedTimes(), ServerStreamExpectation.Times().
	Twice() ServerStreamExpectation
	// UnlimitedTimes indicates that the mock should return the value at least once and there is no max limit in the number
	// of return.
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		Return(`[{"id": 42}]`)
	//		UnlimitedTimes()
	//
	// See: ServerStreamExpectation.Once(), ServerStreamExpectation.Twice(), ServerStreamExpectation.Times().
	UnlimitedTimes() ServerStreamExpectation
	// Times indicates that the mock should only return the indicated number of times.
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		Return(`[{"id": 42}]`)
	//		Times(5)
	//
	// See: ServerStreamExpectation.Once(), ServerStreamExpectation.Twice(), ServerStreamExpectation.UnlimitedTimes().
	Times(i uint) ServerStreamExpectation
	// WaitUntil sets the channel that will block the mocked return until its closed
	// or a message is received.
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		WaitUntil(time.After(time.Second)).
	//		Return(`[{"message": "hello world!"}]`)
	//
	// See: ServerStreamExpectation.After().
	WaitUntil(w <-chan time.Time) ServerStreamExpectation
	// After sets how long to block until the call returns.
	//
	//	Server.ExpectServerStream("grpctest.Service/ListItems").
	//		After(time.Second).
	//		Return(`[{"message": "hello world!"}]`)
	//
	// See: ServerStreamExpectation.WaitUntil().
	After(d time.Duration) ServerStreamExpectation
}

ServerStreamExpectation represents the expectation for a server-stream request.

nolint: interfacebloat

type ServerStreamHandler added in v0.22.0

type ServerStreamHandler interface {
	// WaitFor waits for a duration before running the next step.
	WaitFor(d time.Duration) ServerStreamHandler
	// AddHeader adds a value to the header for sending.
	//
	// See: ServerStreamHandler.SetHeader().
	AddHeader(key, value string) ServerStreamHandler
	// SetHeader sets all the header for sending.
	//
	// See: ServerStreamHandler.AddHeader().
	SetHeader(header map[string]string) ServerStreamHandler
	// SendHeader sends the header.
	SendHeader() ServerStreamHandler
	// Send sends a single message.
	Send(v interface{}) ServerStreamHandler
	// SendMany send multiple messages.
	SendMany(v interface{}) ServerStreamHandler
	// ReturnError sets the response error.
	//
	// See: ServerStreamHandler.ReturnErrorf().
	ReturnError(code codes.Code, msg string)
	// ReturnErrorf sets the response error.
	//
	// See: ServerStreamHandler.ReturnError().
	ReturnErrorf(code codes.Code, msg string, args ...interface{})
}

ServerStreamHandler handles a server-stream request step by step.

type T

type T interface {
	Errorf(format string, args ...interface{})
	FailNow()
	Cleanup(func())
}

T is an interface wrapper around *testing.T.

func NoOpT

func NoOpT() T

NoOpT initiates a new T that does nothing.

type UnaryExpectation added in v0.22.0

type UnaryExpectation interface {
	// WithHeader sets an expected header of the given request.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		WithHeader("Locale", "en-US")
	//
	// See: UnaryExpectation.WithHeaders().
	WithHeader(header string, value interface{}) UnaryExpectation
	// WithHeaders sets a list of expected headers of the given request.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		WithHeaders(map[string]interface{}{"Locale": "en-US"})
	//
	// See: UnaryExpectation.WithHeader().
	WithHeaders(headers map[string]interface{}) UnaryExpectation
	// WithPayload sets the expected payload of the given request. It could be []byte, string, or a matcher.Matcher.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		WithPayload(`{"id": 41}`)
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		WithPayload(&Item{Id: 41})
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		WithPayload(func(actual interface{}) (bool, error) {
	//			in, ok := actual.(*Item)
	//			if !ok {
	//				return false, nil
	//			}
	//
	//			return in.Id == 42, nil
	//		})
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		WithPayload(&Item{Id: 41})
	//
	// See: UnaryExpectation.WithPayloadf().
	WithPayload(in interface{}) UnaryExpectation
	// WithPayloadf formats according to a format specifier and use it as the expected payload of the given request.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		WithPayloadf(`{"message": "hello %s"}`, "john")
	//
	// See: UnaryExpectation.WithPayload().
	WithPayloadf(format string, args ...interface{}) UnaryExpectation

	// ReturnCode sets the response code.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		ReturnCode(codes.OK)
	//
	// See: UnaryExpectation.ReturnErrorMessage(), UnaryExpectation.ReturnError(), UnaryExpectation.ReturnErrorf().
	ReturnCode(code codes.Code)
	// ReturnErrorMessage sets the response error message.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		ReturnErrorMessage("Internal Server Error")
	//
	// See: UnaryExpectation.ReturnCode(), UnaryExpectation.ReturnError(), UnaryExpectation.ReturnErrorf().
	ReturnErrorMessage(msg string)
	// ReturnError sets the response error.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		ReturnError(codes.Internal, "Internal Server Error")
	//
	// See: UnaryExpectation.ReturnCode(), UnaryExpectation.ReturnErrorMessage(), UnaryExpectation.ReturnErrorf().
	ReturnError(code codes.Code, msg string)
	// ReturnErrorf sets the response error.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		ReturnErrorf(codes.NotFound, "Item %d not found", 42)
	//
	// See: UnaryExpectation.ReturnCode(), UnaryExpectation.ReturnErrorMessage(), UnaryExpectation.ReturnError().
	ReturnErrorf(code codes.Code, format string, args ...interface{})
	// Return sets the result to return to client.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		Return(`{"message": "hello world!"}`)
	//
	// See: UnaryExpectation.Returnf(), UnaryExpectation.ReturnJSON(), UnaryExpectation.ReturnFile().
	Return(v interface{})
	// Returnf formats according to a format specifier and use it as the result to return to client.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		Returnf(`{"message": %q}`, "hello")
	//
	// See: UnaryExpectation.Return(), UnaryExpectation.ReturnJSON(), UnaryExpectation.ReturnFile().
	Returnf(format string, args ...interface{})
	// ReturnJSON marshals the object using json.Marshal and uses it as the result to return to client.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		ReturnJSON(map[string]string{"foo": "bar"})
	//
	// See: UnaryExpectation.Return(), UnaryExpectation.Returnf(), UnaryExpectation.ReturnFile().
	ReturnJSON(v interface{})
	// ReturnFile reads the file and uses its content as the result to return to client.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		ReturnFile("resources/fixtures/response.json")
	//
	// See: UnaryExpectation.Return(), UnaryExpectation.Returnf(), UnaryExpectation.ReturnJSON().
	ReturnFile(filePath string)

	// Run sets a custom handler to handle the given request.
	//
	//	   Server.ExpectUnary("grpctest.Service/GetItem").
	//			Run(func(ctx context.Context, in interface{}) (interface{}, error) {
	//				return &Item{}, nil
	//			})
	Run(handler func(ctx context.Context, in interface{}) (interface{}, error))

	// Once indicates that the mock should only return the value once.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		Return("hello world!").
	//		Once()
	//
	// See: UnaryExpectation.Twice(), UnaryExpectation.UnlimitedTimes(), UnaryExpectation.Times().
	Once() UnaryExpectation
	// Twice indicates that the mock should only return the value twice.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		Return("hello world!").
	//		Twice()
	//
	// See: UnaryExpectation.Once(), UnaryExpectation.UnlimitedTimes(), UnaryExpectation.Times().
	Twice() UnaryExpectation
	// UnlimitedTimes indicates that the mock should return the value at least once and there is no max limit in the number
	// of return.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		Return("hello world!").
	//		UnlimitedTimes()
	//
	// See: UnaryExpectation.Once(), UnaryExpectation.Twice(), UnaryExpectation.Times().
	UnlimitedTimes() UnaryExpectation
	// Times indicates that the mock should only return the indicated number of times.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		Return("hello world!").
	//		Times(5)
	//
	// See: UnaryExpectation.Once(), UnaryExpectation.Twice(), UnaryExpectation.UnlimitedTimes().
	Times(i uint) UnaryExpectation
	// WaitUntil sets the channel that will block the mocked return until its closed
	// or a message is received.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		WaitUntil(time.After(time.Second)).
	//		Return("hello world!")
	//
	// See: UnaryExpectation.After().
	WaitUntil(w <-chan time.Time) UnaryExpectation
	// After sets how long to block until the call returns.
	//
	//	Server.ExpectUnary("grpctest.Service/GetItem").
	//		After(time.Second).
	//		Return("hello world!")
	//
	// See: UnaryExpectation.WaitUntil().
	After(d time.Duration) UnaryExpectation
}

UnaryExpectation represents the expectation for a unary request.

nolint: interfacebloat

Directories

Path Synopsis
Package assert provides assertions for grpc.
Package assert provides assertions for grpc.
Package errors provides predefined errors.
Package errors provides predefined errors.
Package format formats the requests.
Package format formats the requests.
Package invoker constructs a grpc request and executes it.
Package invoker constructs a grpc request and executes it.
Package matcher provides custom matchers for gRPC requests.
Package matcher provides custom matchers for gRPC requests.
mock
grpc
Package grpc provides mock for grpc types.
Package grpc provides mock for grpc types.
planner
Package planner provides mock for planner.
Package planner provides mock for planner.
Package must panic on error.
Package must panic on error.
Package planner provides functionalities for deciding what expectation matches the given request.
Package planner provides functionalities for deciding what expectation matches the given request.
Package reflect provides a simple reflection on the grpc server.
Package reflect provides a simple reflection on the grpc server.
Package request provides all the expectations for an RPC method.
Package request provides all the expectations for an RPC method.
Package service provides service definition.
Package service provides service definition.
Package stream provides functions to send or receive messages using a grpc stream.
Package stream provides functions to send or receive messages using a grpc stream.
Package streamer provides functionalities to work with server-side RPC stream.
Package streamer provides functionalities to work with server-side RPC stream.
Package test provides helpers for testing grpcmock.
Package test provides helpers for testing grpcmock.
Package value provides functionalities to convert a generic value to string.
Package value provides functionalities to convert a generic value to string.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL