Leave a Comment
Golang: testing http and grpc servers
Table of Contents
HTTP server
is quite easy to test — here is a nice video about it:
GRPC server
is a little bit trickier to test.
Here’s an example (it won’t compile, but the main idea is this):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
import ( "context" "fmt" "log" "net" "testing" "time" "google.golang.org/grpc" "google.golang.org/grpc/test/bufconn" desc "path to protobuf generated file" ) func TestImplementation_GRPCRouting_GetPositionByID_ShouldOK(t *testing.T) { var requestedID uint64 = 3 ctx := context.TODO() srv, listener := startGRPCServer(prepareImplementation()) // it is here to properly stop the server defer func() {time.Sleep(10 * time.Millisecond)}() defer srv.Stop() conn, err := grpc.DialContext(ctx, "", grpc.WithContextDialer(getBufDialer(listener)), grpc.WithInsecure()) if err != nil { t.Fatalf("failed to dial: %v", err) } defer conn.Close() client := desc.NewVacanciesClient(conn) resp, err := client.GetPositionByID(ctx, &desc.PositionByIDRequest{Id: requestedID}) if err != nil { t.Fatalf("unexpected error: %v", err) } if resp.GetId() != requestedID { t.Fatalf("expected id=%d, got %d", requestedID, resp.GetId()) } } func startGRPCServer(impl *vacancies.Implementation) (*grpc.Server, *bufconn.Listener) { bufferSize := 1024 * 1024 listener := bufconn.Listen(bufferSize) srv := grpc.NewServer() impl.GetDescription().RegisterGRPC(srv) go func() { if err := srv.Serve(listener); err != nil { log.Fatalf("failed to start grpc server: %v", err) } }() return srv, listener } func getBufDialer(listener *bufconn.Listener) func(context.Context, string) (net.Conn, error) { return func(ctx context.Context, url string) (net.Conn, error) { return listener.Dial() } } func prepareImplementation(positions ...*models.Position) *vacancies.Implementation { if len(positions) == 0 { positions = []*models.Position{} impl := &vacancies.Implementation{ PositionStorage: models.NewPositionStorage(positions), } return impl } |
That code was inspired by this answer — https://stackoverflow.com/a/52080545/801426
Similar Posts
LEAVE A COMMENT
Для отправки комментария вам необходимо авторизоваться.