Testing gRPC Services
1. Writing Unit Tests for Services
Example: Test service method directly
func TestGetUser(t *testing.T) {
s := &userServer{repo: newFakeRepo()}
res, err := s.GetUser(context.Background(), &userv1.GetUserRequest{Id: "u1"})
require.NoError(t, err)
require.Equal(t, "Ada", res.Name)
}
2. Using bufconn for In-Memory Server
Example: bufconn listener
import "google.golang.org/grpc/test/bufconn"
lis := bufconn.Listen(1024 * 1024)
srv := grpc.NewServer()
userv1.RegisterUserServiceServer(srv, &userServer{})
go srv.Serve(lis)
conn, _ := grpc.NewClient("passthrough:///bufnet",
grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) { return lis.Dial() }),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
3. Mocking gRPC Server
| Tool | Detail |
|---|---|
| Hand-rolled fake | Implement UnimplementedXServer |
| gomock + mockgen | Generate from interface |
| testify/mock | Expressive assertions |
4. Mocking gRPC Client
5. Testing Unary RPCs
| Assert | Detail |
|---|---|
| Response equality | proto.Equal or cmp with protocmp.Transform() |
| Error code | status.Code(err) == codes.NotFound |
| Error details | Inspect st.Details() |
6. Testing Streaming RPCs
Example: Drain server stream
stream, _ := client.ListUsers(ctx, &userv1.ListUsersRequest{})
var got []*userv1.User
for {
u, err := stream.Recv()
if errors.Is(err, io.EOF) { break }
require.NoError(t, err)
got = append(got, u)
}
require.Len(t, got, 3)
7. Testing Error Cases
| Case | Detail |
|---|---|
| Invalid input | Expect INVALID_ARGUMENT |
| Missing entity | Expect NOT_FOUND |
| Auth failure | Expect UNAUTHENTICATED / PERMISSION_DENIED |
| Timeout | Cancel ctx, expect DEADLINE_EXCEEDED |
8. Testing Interceptors
| Pattern | Detail |
|---|---|
| Call directly | Pass fake handler closure |
| With bufconn | End-to-end interception |
9. Using Test Doubles
| Double | Use |
|---|---|
| Fake | In-memory repo with real logic |
| Stub | Hard-coded responses |
| Mock | Verifies interaction |
| Spy | Records calls only |
10. Implementing Integration Tests
| Tool | Detail |
|---|---|
| testcontainers-go | Spin up Postgres/Redis per test |
| docker compose | Multi-service env |
| grpcurl in scripts | Black-box smoke tests |
11. Implementing Load Tests
| Tool | Detail |
|---|---|
| ghz | gRPC-native load tester |
| k6 + xk6-grpc | Scripted scenarios |
| Vegeta + gRPC wrapper | Custom harness |