Documentation
¶
Overview ¶
Package grpcmock provides functionalities for testing grpc client and server.
Index ¶
- func FindServerMethod(srv *Server, method string) *service.Method
- func InvokeBidirectionalStream(ctx context.Context, method string, handle ClientStreamHandler, ...) error
- func InvokeClientStream(ctx context.Context, method string, handle ClientStreamHandler, out any, ...) error
- func InvokeServerStream(ctx context.Context, method string, in any, handle ClientStreamHandler, ...) error
- func InvokeUnary(ctx context.Context, method string, in any, out any, opts ...InvokeOption) error
- func MatchClientStreamMsgCount(expected int) func() (string, matcher.MatchFn)
- type BidirectionalStreamExpectation
- type ClientStreamExpectation
- type ClientStreamHandler
- type ContextDialer
- type InvokeOption
- func WithBufConnDialer(l *bufconn.Listener) InvokeOption
- func WithCallOptions(opts ...grpc.CallOption) InvokeOption
- func WithContextDialer(d ContextDialer) InvokeOption
- func WithDialOptions(opts ...grpc.DialOption) InvokeOption
- func WithHeader(key, value string) InvokeOption
- func WithHeaders(header map[string]string) InvokeOption
- func WithInsecure() InvokeOption
- type Server
- func (s *Server) Address() string
- func (s *Server) Close() error
- func (s *Server) ExpectBidirectionalStream(method string) BidirectionalStreamExpectation
- func (s *Server) ExpectClientStream(method string) ClientStreamExpectation
- func (s *Server) ExpectServerStream(method string) ServerStreamExpectation
- func (s *Server) ExpectUnary(method string) UnaryExpectation
- func (s *Server) ExpectationsWereMet() error
- func (s *Server) ResetExpectations()
- func (s *Server) Serve()
- func (s *Server) WithPlanner(p planner.Planner) *Server
- func (s *Server) WithTest(t T) *Server
- type ServerMocker
- type ServerMockerWithContextDialer
- type ServerOption
- func ChainStreamInterceptor(interceptors ...grpc.StreamServerInterceptor) ServerOption
- func ChainUnaryInterceptor(interceptors ...grpc.UnaryServerInterceptor) ServerOption
- func ConnectionTimeout(d time.Duration) ServerOption
- func Creds(c credentials.TransportCredentials) ServerOption
- func InTapHandle(h tap.ServerInHandle) ServerOption
- func InitialConnWindowSize(sz int32) ServerOption
- func InitialWindowSize(sz int32) ServerOption
- func KeepaliveEnforcementPolicy(kep keepalive.EnforcementPolicy) ServerOption
- func KeepaliveParams(kp keepalive.ServerParameters) ServerOption
- func MaxConcurrentStreams(n uint32) ServerOption
- func MaxHeaderListSize(sz uint32) ServerOption
- func MaxRecvMsgSize(m int) ServerOption
- func MaxSendMsgSize(m int) ServerOption
- func ReadBufferSize(sz int) ServerOption
- func RegisterService(registerFunc any) ServerOption
- func RegisterServiceFromInstance(id string, svc any) ServerOption
- func RegisterServiceFromMethods(serviceMethods ...service.Method) ServerOption
- func StatsHandler(h stats.Handler) ServerOption
- func StreamInterceptor(i grpc.StreamServerInterceptor) ServerOption
- func UnaryInterceptor(i grpc.UnaryServerInterceptor) ServerOption
- func UnknownServiceHandler(streamHandler grpc.StreamHandler) ServerOption
- func WithAddress(addr string) ServerOption
- func WithListener(l net.Listener) ServerOption
- func WithPlanner(p planner.Planner) ServerOption
- func WithPort(port int) ServerOption
- func WriteBufferSize(sz int) ServerOption
- type ServerStreamExpectation
- type ServerStreamHandler
- type T
- type UnaryExpectation
Examples ¶
- MockServer
- MockServerWithBufConn
- NewServer (BidirectionalStreamMethod)
- NewServer (ClientStreamMethod)
- NewServer (ClientStreamMethod_customHandler)
- NewServer (ServerStreamMethod)
- NewServer (ServerStreamMethod_customHandler)
- NewServer (ServerStreamMethod_customStreamBehaviors)
- NewServer (UnaryMethod)
- NewServer (UnaryMethod_customHandler)
- NewServer (WithPort)
- RegisterService
- RegisterServiceFromInstance
- RegisterServiceFromMethods
- Server (FirstMatch_planner)
- Server.WithPlanner
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FindServerMethod ¶
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 any, opts ...InvokeOption, ) error
InvokeClientStream invokes a client-stream method.
func InvokeServerStream ¶
func InvokeServerStream( ctx context.Context, method string, in any, handle ClientStreamHandler, opts ...InvokeOption, ) error
InvokeServerStream invokes a server-stream method.
func InvokeUnary ¶
func InvokeUnary( ctx context.Context, method string, in any, out any, opts ...InvokeOption, ) error
InvokeUnary invokes a unary method.
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 any) BidirectionalStreamExpectation
// WithHeaders sets a list of expected headers of the given request.
//
// Server.ExpectBidirectionalStream("grpctest.Service/TransformItems").
// WithHeaders(map[string]any{"Locale": "en-US"})
//
// See: BidirectionalStreamExpectation.WithHeader().
WithHeaders(headers map[string]any) 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 ...any)
// 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 any) ClientStreamExpectation
// WithHeaders sets a list of expected headers of the given request.
//
// Server.ExpectClientStream("grpctest.Service/CreateItems").
// WithHeaders(map[string]any{"Locale": "en-US"})
//
// See: ClientStreamExpectation.WithHeader().
WithHeaders(headers map[string]any) 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 any) 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 ...any) 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 ...any)
// 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 any)
// 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 ...any)
// 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]any{"num_items": 1})
//
// See: ClientStreamExpectation.Return(), ClientStreamExpectation.Returnf(), ClientStreamExpectation.ReturnFile().
ReturnJSON(v any)
// 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) (any, error) {
// return &grpctest.CreateItemsResponse{NumItems: 1}, nil
// })
Run(handler func(ctx context.Context, s grpc.ServerStream) (any, 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 any) ClientStreamHandler
RecvAll reads everything from the stream and put into the output.
func SendAndRecvAll ¶
func SendAndRecvAll(in any, out any) ClientStreamHandler
SendAndRecvAll sends and receives messages to and from grpc server in turn until server sends the io.EOF.
func (ClientStreamHandler) Handle ¶
func (h ClientStreamHandler) Handle(s grpc.ClientStream) error
Handle handles a client stream.
type ContextDialer ¶
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 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_FullMethodName).
WithPayload(&grpctest.GetItemRequest{Id: 1}).
Return(&grpctest.Item{Id: 1, Name: "FoodUniversity"})
s.ExpectUnary(grpctest.ItemService_GetItem_FullMethodName).
WithPayload(&grpctest.GetItemRequest{Id: 2}).
Return(&grpctest.Item{Id: 2, Name: "Metaverse"})
s.ExpectUnary(grpctest.ItemService_GetItem_FullMethodName).
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_FullMethodName, &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_FullMethodName).
Run(func(_ 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.GetId())
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_FullMethodName,
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_FullMethodName).
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_FullMethodName,
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_FullMethodName).
WithPayload(grpcmock.MatchClientStreamMsgCount(3)).
Run(func(_ context.Context, s grpc.ServerStream) (any, 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.GetId() > 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_FullMethodName,
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_FullMethodName).
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_FullMethodName,
&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_FullMethodName).
Run(func(_ context.Context, _ any, 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_FullMethodName,
&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_FullMethodName).
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_FullMethodName,
&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_FullMethodName).
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_FullMethodName, &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_FullMethodName).
WithPayload(&grpctest.GetItemRequest{Id: 42}).
Run(func(ctx context.Context, in any) (any, 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.GetId(),
Locale: locale,
Name: fmt.Sprintf("Item #%d", req.GetId()),
}, nil
})
},
)
defer srv.Close() //nolint: errcheck
// Call the service.
out := &grpctest.Item{}
err := grpcmock.InvokeUnary(context.Background(),
grpctest.ItemService_GetItem_FullMethodName, &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_FullMethodName).
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) 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 ¶
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) WithPlanner ¶
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_FullMethodName).
Run(func(context.Context, any) (any, error) {
panic(`this never happens`)
})
},
)
defer srv.Close() //nolint: errcheck
// Call the service.
err := grpcmock.InvokeUnary(context.Background(),
grpctest.ItemService_GetItem_FullMethodName, &grpctest.GetItemRequest{Id: 41}, &grpctest.Item{},
grpcmock.WithInsecure(),
grpcmock.WithBufConnDialer(buf),
)
fmt.Println(err)
}
Output: rpc error: code = Internal desc = always fail
type ServerMocker ¶
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_FullMethodName).
WithPayload(&grpctest.GetItemRequest{Id: 41}).
Return(&grpctest.Item{
Id: 41,
Locale: "en-US",
Name: "Item #41",
})
},
)(t)
// Call the service.
out := &grpctest.Item{}
method := srv.Address() + grpctest.ItemService_GetItem_FullMethodName
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_FullMethodName).
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_FullMethodName, &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 ¶
func Creds(c credentials.TransportCredentials) ServerOption
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 any) 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_FullMethodName).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_FullMethodName).
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_FullMethodName, &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 any) ServerOption
RegisterServiceFromInstance registers a new service using the generated server interface.
grpcmock.MockUnstartedServer(
grpcmock.RegisterServiceFromInstance(grpctest.ItemService_ServiceDesc.ServiceName, (*grpctest.ItemServiceServer)(nil)),
func(s *grpcmock.Server) {
s.ExpectUnary(grpctest.ItemService_GetItem_FullMethodName).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_ServiceDesc.ServiceName, (*grpctest.ItemServiceServer)(nil)),
grpcmock.WithListener(buf),
func(s *grpcmock.Server) {
s.ExpectUnary(grpctest.ItemService_GetItem_FullMethodName).
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_FullMethodName, &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_ServiceDesc.ServiceName,
MethodName: "GetItem",
MethodType: service.TypeUnary,
Input: &grpctest.GetItemRequest{},
Output: &grpctest.Item{},
}),
func(s *grpcmock.Server) {
s.ExpectUnary(grpctest.ItemService_GetItem_FullMethodName).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_ServiceDesc.ServiceName,
MethodName: "GetItem",
MethodType: service.TypeUnary,
Input: &grpctest.GetItemRequest{},
Output: &grpctest.Item{},
}),
grpcmock.WithListener(buf),
func(s *grpcmock.Server) {
s.ExpectUnary(grpctest.ItemService_GetItem_FullMethodName).
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_FullMethodName, &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 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_FullMethodName).UnlimitedTimes().
Return(&grpctest.Item{})
},
)(t)
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 any) ServerStreamExpectation
// WithHeaders sets a list of expected headers of the given request.
//
// Server.ExpectServerStream("grpctest.Service/ListItems").
// WithHeaders(map[string]any{"Locale": "en-US"})
//
// See: ServerStreamExpectation.WithHeader().
WithHeaders(headers map[string]any) 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 any) 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 ...any) 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 ...any)
// 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 any)
// 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 ...any)
// 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 any)
// 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 any, srv any) error {
// srv := out.(grpc.ServerStreamer)
//
// return srv.SendMsg(grpctest.Item{Id: 42})
// })
Run(handler func(ctx context.Context, in any, 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 any) ServerStreamHandler
// SendMany send multiple messages.
SendMany(v any) 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 ...any)
}
ServerStreamHandler handles a server-stream request step by step.
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 any) UnaryExpectation
// WithHeaders sets a list of expected headers of the given request.
//
// Server.ExpectUnary("grpctest.Service/GetItem").
// WithHeaders(map[string]any{"Locale": "en-US"})
//
// See: UnaryExpectation.WithHeader().
WithHeaders(headers map[string]any) 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 any) (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 any) 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 ...any) 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 ...any)
// 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 any)
// 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 ...any)
// 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 any)
// 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 any) (any, error) {
// return &Item{}, nil
// })
Run(handler func(ctx context.Context, in any) (any, 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
Source Files
¶
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. |
