I'd like to write a unit test in which I run an ephemeral gRPC server which is started in a separate Goroutine within the test and stopped after the test runs. To this end, I've tried adapting the 'Hello, world' example from this tutorial (https://grpc.io/docs/languages/go/quickstart/) to one in which instead of a server and a client with separate main.go
s, there is a single test function which starts the server asynchronously and subsequently makes the client connection using the grpc.WithBlock()
option.
I've put the simplified example in this repository, https://github.com/kurtpeek/grpc-helloworld; here is the main_test.go
:
package main
import (
"context"
"fmt"
"log"
"net"
"testing"
"time"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"google.golang.org/grpc/examples/helloworld/helloworld"
)
const (
port = ":50051"
)
type server struct {
helloworld.UnimplementedGreeterServer
}
func (s *server) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
log.Printf("Received: %v", in.GetName())
return &helloworld.HelloReply{Message: "Hello " + in.GetName()}, nil
}
func TestHelloWorld(t *testing.T) {
lis, err := net.Listen("tcp", port)
require.NoError(t, err)
s := grpc.NewServer()
helloworld.RegisterGreeterServer(s, &server{})
go s.Serve(lis)
defer s.Stop()
log.Println("Dialing gRPC server...")
conn, err := grpc.Dial(fmt.Sprintf("localhost:%s", port), grpc.WithInsecure(), grpc.WithBlock())
require.NoError(t, err)
defer conn.Close()
c := helloworld.NewGreeterClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
log.Println("Making gRPC request...")
r, err := c.SayHello(ctx, &helloworld.HelloRequest{Name: "John Doe"})
require.NoError(t, err)
log.Printf("Greeting: %s", r.GetMessage())
}
The problem is that when I run this test, it times out:
> go test -timeout 10s ./... -v
=== RUN TestHelloWorld
2020/06/30 11:17:45 Dialing gRPC server...
panic: test timed out after 10s
I'm having trouble seeing why a connection is not made? It seems to me that the server is started correctly...