【问题标题】:mock grpc client request and response using testify使用 testify 模拟 grpc 客户端请求和响应
【发布时间】: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


    【解决方案1】:

    我设法用 mockery 包做到了,并通过 brew 安装了它

    mockery --name=UserServiceClient --unroll-variadic=False
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      • 2011-02-01
      • 2018-02-09
      • 2014-08-14
      • 1970-01-01
      • 2021-12-08
      • 2017-04-15
      相关资源
      最近更新 更多