Testing a gRPC service

前端 未结 8 530
旧巷少年郎
旧巷少年郎 2020-12-12 15:05

I\'d like to test a gRPC service written in Go. The example I\'m using is the Hello World server example from the grpc-go repo.

The protobuf definition is as follows

8条回答
  •  不思量自难忘°
    2020-12-12 15:27

    I think you're looking for the google.golang.org/grpc/test/bufconn package to help you avoid starting up a service with a real port number, but still allowing testing of streaming RPCs.

    import "google.golang.org/grpc/test/bufconn"
    
    const bufSize = 1024 * 1024
    
    var lis *bufconn.Listener
    
    func init() {
        lis = bufconn.Listen(bufSize)
        s := grpc.NewServer()
        pb.RegisterGreeterServer(s, &server{})
        go func() {
            if err := s.Serve(lis); err != nil {
                log.Fatalf("Server exited with error: %v", err)
            }
        }()
    }
    
    func bufDialer(context.Context, string) (net.Conn, error) {
        return lis.Dial()
    }
    
    func TestSayHello(t *testing.T) {
        ctx := context.Background()
        conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure())
        if err != nil {
            t.Fatalf("Failed to dial bufnet: %v", err)
        }
        defer conn.Close()
        client := pb.NewGreeterClient(conn)
        resp, err := client.SayHello(ctx, &pb.HelloRequest{"Dr. Seuss"})
        if err != nil {
            t.Fatalf("SayHello failed: %v", err)
        }
        log.Printf("Response: %+v", resp)
        // Test for output here.
    }
    

    The benefit of this approach is that you're still getting network behavior, but over an in-memory connection without using OS-level resources like ports that may or may not clean up quickly. And it allows you to test it the way it's actually used, and it gives you proper streaming behavior.

    I don't have a streaming example off the top of my head, but the magic sauce is all above. It gives you all of the expected behaviors of a normal network connection. The trick is setting the WithDialer option as shown, using the bufconn package to create a listener that exposes its own dialer. I use this technique all the time for testing gRPC services and it works great.

提交回复
热议问题