我需要为一个函数编写一个单元测试,该函数在其源代码中调用不同 gRPC 服务的 gRPC 方法。我的测试结果出现严重错误,因为 gRPC 服务未在我的计算机上运行。我想在测试中创建一个虚拟服务,并且该服务必须为源代码内的方法调用提供服务。我怎么做?
编辑:详细信息源函数:
func (s *mainType) MainGenerateBearerToken(inputs...)(output) {
response, err := s.Subtype.SubGenerateBearerToken(context, authnPass, ttl)
if err != nil {
return nil, err
}
return &models.OCITokenResponse{Token: response.Token, ExpiresIn: ttl}, nil
}
func(cl *Subtype) SubGenerateBearerToken(context,authnPass, ttl) (*BearerTokenResponse, error) {
resp,err := pb.NewGrpcClient(cl.Conn).GetBearerToken_grpc(ctx, &pb.GetBearerTokenRequest{AuthnToken, BearerTtlValue:ttlNum)
return &BearerTokenResponse{Token}, err
}
Run Code Online (Sandbox Code Playgroud)
我正在为 MainGenerateBearerToken() 函数编写测试,该函数调用 SubGenerateBearerToken(),其中调用 grpc 方法。
gRPC 服务客户端是一个常规的 Go 接口。
您可以使用gomock或moq等工具为任何 Go 接口生成模拟。
$ go install github.com/golang/mock/mockgen@v1.6.0
$ mockgen -source=my_service.pb.go MyServiceClient
Run Code Online (Sandbox Code Playgroud)
或者
$ go install github.com/matryer/moq@v0.2.5
$ moq -pkg mock -out mock/my_service.go . MyServiceClient
Run Code Online (Sandbox Code Playgroud)
这将生成mock.MyServiceClientMock该实现MyServiceClient。然后您可以在单元测试中使用它而不是真正的 gRPC 客户端。
使用最小起订量的完整示例:
my_service.proto:
syntax = "proto3";
package main;
option go_package = "main";
service MyService {
rpc Hello(HelloMesage) returns (HelloMesage) {}
}
message HelloMesage {
string msg = 1;
}
Run Code Online (Sandbox Code Playgroud)
main.go:
package main
import context "context"
//go:generate protoc --go_out=plugins=grpc:. -I=. my_service.proto
//go:generate moq -out my_service_mock.go . MyServiceClient
func CallHello(myService MyServiceClient) (*HelloMesage, error) {
return myService.Hello(context.TODO(), &HelloMesage{Msg: "hello"})
}
func main() {
// (omitted) call grpc normally ...
}
Run Code Online (Sandbox Code Playgroud)
main_test.go:
package main
import (
context "context"
"testing"
"github.com/stretchr/testify/assert"
grpc "google.golang.org/grpc"
)
func TestCallHello(t *testing.T) {
myServiceClient := &MyServiceClientMock{
HelloFunc: func(ctx context.Context, in *HelloMesage, opts ...grpc.CallOption) (*HelloMesage, error) {
return &HelloMesage{Msg: in.Msg + " reply"}, nil
},
}
res, err := CallHello(myServiceClient)
assert.NoError(t, err)
assert.Equal(t, "hello reply", res.Msg)
}
Run Code Online (Sandbox Code Playgroud)
跑步:
$ go mod init myservice
$ go mod tidy
$ go generate
$ go test
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9439 次 |
| 最近记录: |