【发布时间】:2022-12-03 16:49:35
【问题描述】:
我一直在尝试模拟我的 grpc 客户端/服务器来控制响应。
我想要实现的是 flex testify 为我们提供模拟,并使用 once(),times() 想法。
所以我将进一步解释假设我有一个运行以下命令的程序: 我想控制 client.getUser() 迭代的每个响应
type DB struct {
api serviceAPI
}
type service struct {
}
type serviceAPI interface {
getClient() (pb.UserServiceClient, *grpc.ClientConn, error)
}
func (db *DB) getNextUser()(*UserAcc,error){
client := db.api.getClient()
var index uint64 = 0
for {
user = client.getUser(context.Background(), &pb.GetUserRequest{Index: index})
if(user == nil){
return nil,nil
}
if user(!=nil){
fmt.Printl(user)
}
}
}
func (s service) getClient() (pb.UserServiceClient, *grpc.ClientConn, error) {
addr := GetAgentAddress()
conn, _ := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
client := pb.NewUserServiceClient(conn)
return client, conn, nil
}
原.go
message GetUserRequest{
uint64 index = 1;
}
message GetUserResponse{
bytes user = 1;
}
service userService {
rpc GetUser (GetUserRequest) returns (GetUserResponse);
}
user_grpc.pb.go
type UserServiceClient interface {
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error)
UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error)
main_test.go
type MainTestSuite struct {
suite.Suite
}
type serviceMock struct {
mock.Mock
}
type clientMock struct {
mock.Mock
}
func (c *clientMock) UpdateUser(ctx context.Context, in *pb.UpdateUserRequest, opts ...grpc.CallOption) (*pb.UpdateUserResponse, error) {
//TODO implement me
panic("implement me")
}
func (c *clientMock) GetUser(ctx context.Context, in *pb.GetUserRequest, opts ...grpc.CallOption) (*pb.GetUserResponse, error) {
args := c.Called(ctx, in, opts)
return args.Get(0).(*pb.GetUserResponse), args.Error(1)
}
func (service *serviceMock) getClient() (pb.UserServiceClient, *grpc.ClientConn, error) {
args := service.Called()
return args.Get(0).(clientMock), args.Get(1).(*grpc.ClientConn), args.Error(2)
}
func (suite *MainTestSuite) TestGetNextUser() {
t := suite.T()
t.Run("Should successfully get the next User", func(t *testing.T) {
mServiceApi := serviceMock{}
ClientMock := clientMock{}
mServiceApi.On("getClient").Return(ClientMock, nil, nil)
ClientMock.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(&pb.GetUserResponse{
User: []bytes("something"),
}, nil).once()
ClientMock.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(&pb.GetUserResponse{
User: []bytes("some other user"),
}, nil).once()
ClientMock.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(&pb.GetUserResponse{
User: []bytes("something"),
}, nil).once()
db := DB{
api: &mServiceApi,
}
nextUser ,_ := db.getNextUser(true)
assert.Nil(t, nextUser)
})
}
我希望客户端 grpc 的 GetUser 命令的每次迭代都使用 testify 的 once() 或 times() 获得不同的答案
我是在以正确的方式嘲笑 grpc 客户端吗?
现在我遇到以下问题:
Cannot use 'args.Get(0).(clientMock)' (type clientMock) as the type pb.UserServiceClient Type does not implement 'pb.UserServiceClient' as the 'UpdateUser' method has a pointer receiver.
知道为什么吗?
【问题讨论】:
标签: unit-testing go grpc grpc-go