Environment
go version go1.17.4 linux/amd64
libprotoc 3.6.1
Problem
I'm testing grpc server and client implemented by Go.
First, I made proto definition and generate pb codes by protoc command.
I referred this solution.
Following the error is printed by minimum codes to reproduce my error.
Error
$ go test
--- FAIL: TestHello (0.00s)
main_test.go:49: failed to Hello: rpc error: code = Unimplemented desc = method Hello not implemented
FAIL
exit status 1
FAIL github.com/Asuha-a/test/test 0.003s
Code
hello.proto
syntax = "proto3";
option go_package = "github.com/Asuha-a/test/pb";
package hello;
service Hello {
rpc Hello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string foo = 1;
}
message HelloReply {
string bar = 1;
}
main_test.go
package hello_test
import (
"context"
"log"
"net"
"testing"
"github.com/Asuha-a/test/pb"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
)
type server struct {
pb.UnimplementedHelloServer
}
const bufSize = 1024 * 1024
var lis *bufconn.Listener
func init() {
lis = bufconn.Listen(bufSize)
s := grpc.NewServer()
pb.RegisterHelloServer(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 TestHello(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.NewHelloClient(conn)
r, err := client.Hello(ctx, &pb.HelloRequest{
Foo: "foo",
})
if err != nil {
t.Fatalf("failed to Hello: %v", err) //49th line prints the error
}
log.Println(r)
}
CodePudding user response:
In your test you are calling pb.RegisterHelloServer(s, &server{})
using the server
struct. However this struct only embeds pb.UnimplementedHelloServer
and declares no methods. Hence, you can only get codes.Unimplemented
back when calling any of its RPCs.
You have to implement the Hello
rpc on the server
struct:
func (s *server) Hello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{}, nil
}
Note: embedding pb.UnimplementedHelloServer
makes the gRPC server implementations forward compatible at the expense of compile-time checks. To forgo forward compatibility and catch these errors at compile time, you can embed instead pb.UnsafeHelloServer
.