gRPCサービスのテスト
2023-09-07 03:54:21
質問
Go で書かれた gRPC サービスをテストしたいと思います。私が使用しているのは、Hello World サーバーの例で、これは grpc-go レポ .
protobufの定義は以下の通りです。
syntax = "proto3";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
で型が
greeter_server
のメインは
// server is used to implement helloworld.GreeterServer.
type server struct{}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}
例を探してみましたが、GoでgRPCサービスのテストを実装する方法については見つかりませんでした。
どのように解決するのですか?
あなたが探しているのは
google.golang.org/grpc/test/bufconn
パッケージをお探しだと思いますが、これは実際のポート番号でサービスを起動することを避けつつ、ストリーミング RPC をテストできるようにするためのものです。
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.
}
このアプローチの利点は、ネットワークの動作はそのままに、インメモリ接続で、ポートのようなOSレベルのリソースを使用せず、すぐにクリーンアップできるかどうかということです。そして、実際に使用される方法でテストすることができ、適切なストリーミング動作が得られます。
頭の中にストリーミングの例がないのですが、マジックソースは上記のすべてです。これは、通常のネットワーク接続の期待される動作のすべてを提供します。トリックは、図のように WithDialer オプションを設定し、bufconn パッケージを使用して、独自のダイヤラーを公開するリスナーを作成することです。私は gRPC サービスをテストするためにいつもこのテクニックを使用していますが、とてもうまくいきます。
関連
-
[解決済み] Goでスライスを逆に反復処理する方法はありますか?
-
[解決済み] Goプロジェクトの賢明なレイアウト方法とは [終了しました]。
-
[解決済み] マップから構造体への変換
-
[解決済み] ...interface{}の意味 (ドット・ドット・ドット・インターフェース)
-
[解決済み] gc」と「gccgo」の主な相違点は何ですか?
-
[解決済み] コンパイルしたファイルのサイズを小さくするには?
-
[解決済み] 標準入力から整数を読み込む
-
[解決済み] Goで配列をスライスに変換する
-
[解決済み] Goによる2変数のForループ
-
[解決済み] Golang で os/exec で開始したプロセスを終了させる
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Goを使って大きなファイルを効率よくダウンロードするにはどうしたらいいですか?
-
[解決済み] 現在時刻に時・分・秒を足す
-
[解決済み] GoLangで文字列を比較するにはどうしたらいいですか?
-
[解決済み] IntelliJでファイル保存時にgofmtを実行する
-
[解決済み] 構造体のプロパティに名前でアクセスする
-
[解決済み] Go オブジェクトのポインタ値を表示するにはどうすればよいですか?ポインタの値は何を意味するのですか?
-
[解決済み] Go で / に異なるメソッドの http リクエストを処理するにはどうすればよいですか?
-
[解決済み] Goで実行時に構造体の型から新しいインスタンスを作成するにはどうすればよいですか?
-
[解決済み] golangにはブーリアンに対するXOR演算子はないのですか?
-
[解決済み] Golang で os/exec で開始したプロセスを終了させる