[gRPC-Go] 서버 테스트를 네트워크 연결 없이 수행

9552 단어 gRPC

gRPC Server 테스트



gRPC 서버는 일반적으로 TCP 서버를 설정해야 하며 테스트하려고 하면 귀찮습니다.

그래서 통신 부분을 in-memory로 바꿔주는 grpc/test/bufconn 라는 패키지를 이용하면 편리합니다.

bufconn은 네트워크 서버처럼 동작하는 Listener를 가지고 있으며 Dial() 메소드로 클라이언트 연결처럼 동작하는 net.Conn도 가진다는 특징이 있습니다.

bufconn을 사용하여 네트워크 연결없이 테스트



이제 실제로 bufconn을 사용한 테스트를 작성해 보겠습니다.

소스 코드는 다음 리포지토리에도 게시됩니다.
htps : // 기주 b. 코 m / 카 s 타네 아이 / grpc - s sing g-u-th-f f

예를 들면 gRPC 공식 튜토리얼에도 있습니다. 다음과 같은 간단한 RPC로 생각합니다.
syntax = "proto3";

package hello;

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}
protoc 에서 Go 정의 파일을 생성하여 다음과 같은 디렉토리 구성으로 만듭니다.
$ protoc greeter.proto --go_out=plugins=grpc:.
.
├── go.mod
├── go.sum
├── greeter.pb.go
├── greeter.proto
└── server
   ├── server.go
   └── server_test.go
server/ 디렉토리 아래에 두 개의 파일을 만듭니다.
  • server.go 서버 구현
  • server_test.go 서버 테스트 (bufconn을 사용하는 부분)
  • server.go아무것도 특별한 것은 없으며 일반 gRPC 서버 구현 입니다.

    둘째, server_test.go 하지만 여기가 중요합니다!

    gRPC-Go에서는 grpc.Dial()로 서버에 연결하지만 grpc.DialContext(grpc.WithCotnextDialer(...))를 사용합니다.
    WithContextDialer의 내용을 bufconn에 연결 lis.Dial()로 바꾸는 방법입니다.

    server_test.go
    package main
    
    import (
        "context"
        "log"
        "net"
        "testing"
    
        "google.golang.org/grpc"
        "google.golang.org/grpc/test/bufconn"
    
        pb "github.com/castaneai/grpc-testing-with-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.Fatal(err)
            }
        }()
    }
    
    func bufDialer(ctx context.Context, address 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.Fatal(err)
        }
        defer conn.Close()
    
        client := pb.NewGreeterClient(conn)
        resp, err := client.SayHello(ctx, &pb.HelloRequest{Name: "test"})
        if err != nil {
            t.Fatal(err)
        }
    
        if resp.GetMessage() != "Hello test" {
            t.Fatal("hello reply must be 'Hello test'")
        }
    }
    

    이제 테스트를 실행해 보면 즉시 테스트가 통과했습니다!
    $ go test -v ./...
    === RUN   TestSayHello
    2019/10/04 12:50:04 Received: test
    --- PASS: TestSayHello (0.00s)
    PASS
    ok      github.com/castaneai/grpc-testing-with-bufconn/server   0.024s
    

    좋은 웹페이지 즐겨찾기