Documentation ¶
Overview ¶
Package grpctest provides helpers for testing gRPC service implementations over the full gRPC client-server stack.
Index ¶
- func NewClientConn[S any](register func(*grpc.Server, S), impl S, opts ...grpc.ServerOption) (*grpc.ClientConn, func(), error)
- func NewClientConnTB[S any](tb testing.TB, register func(*grpc.Server, S), impl S, ...) *grpc.ClientConn
- func RegisterService[S any](t *Tester, register func(*grpc.Server, S), impl S)
- type Tester
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewClientConn ¶
func NewClientConn[S any](register func(*grpc.Server, S), impl S, opts ...grpc.ServerOption) (*grpc.ClientConn, func(), error)
NewClientConn is a convenience wrapper for registering a single service with a Tester, and returning the ClientConn obtained from Dial(). The returned cleanup function blocks until the underlying grpc.Server stops, and does not need to be called if NewClientConn returns an error.
See Tester.RegisterService() for a description of the arguments.
Example ¶
// This variable declaration is purely demonstrative of the fact that // echo{} implements the interface. var svc pb.EchoServiceServer = &echo{} conn, cleanup, err := NewClientConn(pb.RegisterEchoServiceServer, svc) if err != nil { fmt.Printf("NewClientConn() got err %v; want nil err", err) return } defer cleanup() c := pb.NewEchoServiceClient(conn) resp, err := c.Echo(context.Background(), &pb.Request{Msg: "foobar"}) if err != nil { fmt.Printf("EchoService.Echo() got err %v; want nil err", err) } fmt.Println(resp.Msg)
Output: foobar
func NewClientConnTB ¶
func NewClientConnTB[S any](tb testing.TB, register func(*grpc.Server, S), impl S, opts ...grpc.ServerOption) *grpc.ClientConn
NewClientConnTB is equivalent to NewClientConn() except that all errors are reported on tb.Fatal() and cleanup is handled by tb.Cleanup().
func RegisterService ¶
RegisterService registers a service implementation with the Tester's underlying grpc.Server. The register argument must be a RegisterXServer() function from a proto file, where X is the name of some service.
If only one service needs to be registered, rather use NewClientConn().
This is a top-level function instead of a method on Tester as method's can't be generic.
Types ¶
type Tester ¶
type Tester struct {
// contains filtered or unexported fields
}
A Tester wraps a grpc.Server, with connections made over a bufconn.Listener.
Example ¶
st := New() defer st.Close() // Register as many services as necessary. If only one is needed, rather use // NewClientConn() which handles all of the additional steps, and accepts // identical arguments to RegisterService(). // This variable declaration is purely demonstrative of the fact that // echo{} implements the interface. var svc pb.EchoServiceServer = &echo{} if err := st.RegisterService(pb.RegisterEchoServiceServer, svc); err != nil { fmt.Printf("RegisterService() got err %v", err) return } done := make(chan struct{}) go func() { defer close(done) st.Serve() }() conn, err := st.Dial() if err != nil { fmt.Printf("%T.Dial() got err %v", st, err) return } c := pb.NewEchoServiceClient(conn) resp, err := c.Echo(context.Background(), &pb.Request{Msg: "hello world"}) if err != nil { fmt.Printf("EchoService.Echo() got err %v", err) return } fmt.Println(resp.Msg) st.Close() // Not entirely necessary; but demonstrates that the Server has stopped. <-done
Output: hello world
func New ¶
func New(opts ...grpc.ServerOption) *Tester
New returns a new Tester. Close() must be called to clean up, even if Serve() is never called.
func NewWithRegistered ¶
func NewWithRegistered[S any](register func(*grpc.Server, S), impl S, opts ...grpc.ServerOption) (*Tester, func())
NewWithRegistered is a convenience wrapper for registering a single service with a Tester, which is then returned. The returned cleanup function blocks until the underlying grpc.Server stops.
See Tester.RegisterService() for a description of the arguments.
func NewWithRegisteredTB ¶
func NewWithRegisteredTB[S any](tb testing.TB, register func(*grpc.Server, S), impl S, opts ...grpc.ServerOption) *Tester
NewWithRegisteredTB is equivalent to NewWithRegistered() except that cleanup is handled by tb.Cleanup().
func (*Tester) Close ¶
Close gracefully stops the grpc.Server if Serve was called, and closes the Listener. It must be called even if Serve() was not.
func (*Tester) Dial ¶
func (t *Tester) Dial(opts ...grpc.DialOption) (*grpc.ClientConn, error)
Dial calls grpc.Dial() with a dialer that will connect to the underlying bufconn.Listener with the provided options, which must not include a dialer themselves. All connections use a grpc.WithInsecure() option.
func (*Tester) DialOpts ¶
func (t *Tester) DialOpts(user ...grpc.DialOption) []grpc.DialOption
DialOpts extends the provided options with those necessary to connect to the Tester's grpc.Server.
func (*Tester) RegisterService
deprecated
RegisterService registers a service implementation with the underlying grpc.Server. The registerFunc argument must be a RegisterXServer() function from a proto file, where X is the name of some service. The implementation argument must implement the respective XServer interface.
If only one service needs to be registered, rather use NewClientConn().
Deprecated: use the top-level function RegisterService() as it provides static type safety through generics. Methods can't be parameterised, so this uses reflection as it pre-dates the introduction of generics.