为了账号安全,请及时绑定邮箱和手机立即绑定

尝试在 TCP 侦听器上提供服务时,由于超时,Go 测试明显失败

尝试在 TCP 侦听器上提供服务时,由于超时,Go 测试明显失败

Go
慕后森 2023-07-10 10:10:02
我有这个单元测试:func TestServer(t *testing.T) {    db := prepareDBConn(t)    defer db.Close()    lis := bufconn.Listen(1024 * 1024)    t.Logf("Opened listener: %v", lis)    grpcServer := grpc.NewServer(        withUnaryInterceptor(),    )    t.Logf("Opened grpc server: %v", grpcServer)    signKey := getSignKey()    if signKey == nil {        t.Fatal("Failed to find or parse RSA private key")    }    verifyKeyErr := setVerifyKey()    if verifyKeyErr != nil {        t.Fatal("Failed to find or parse RSA public key")    }    pb.RegisterAuthServiceServer(grpcServer, newAuthServiceServer(db, signKey))    err := grpcServer.Serve(lis)    if err != nil {        t.Fatalf("Failed to listen: %+v", err)    }}如果我注释掉最后 4 行:    // err := grpcServer.Serve(lis)    // if err != nil {    //   t.Fatalf("Failed to listen: %+v", err)    // }每次都会通过,但无论出于何种原因,它都会在线路上变得很糟糕err := grpcServer.Server(lis)。我尝试过使用真正的 TCP 侦听器(lis := bufconn.Listen与交换lis := net.Listen("tcp"))。它没有告诉我出了什么问题(除了超时)并且似乎还参考了其他库的测试?我通过调用测试vs-code,它使用以下命令:/usr/local/bin/go test -timeout 30s -run ^(TestServer)$我可以构建并运行该包,它完全按照我的预期工作,并且不会在那条线上失败,所以我认为我在单元测试方面做错了一些事情,但在这一点上我没有太多要做的,而且我不这样做对 go 测试了解不多。
查看完整描述

2 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

正如我所看到的,您正在尝试对 gRPC 服务器进行单元测试。您尝试使用的策略对于单元测试来说是相当过大的。

为简单起见,您应该有一个服务器结构来保存互连的部分,例如:数据库连接。

因此,您只需初始化数据库连接并将其传递给服务器结构。这是模拟数据库的正确位置。之后,您将拥有启动 gRPC 服务器实例,因为您不需要拨打 gRPC 进行单元测试。

然后,您可以在初始化的 Server 实例上调用预期的 rpc 函数。它看起来更加干净和可维护。


查看完整回答
反对 回复 2023-07-10
?
富国沪深

TA贡献1790条经验 获得超9个赞

服务是一个阻塞调用。它将等待新的连接并在它们进来时无限期地处理它们。这就是它的全部目的 - 在服务器关闭或崩溃之前它不会返回。根据文档Serve

Serve 接受监听器上的传入连接,为每个连接创建一个新的 ServerTransport 和服务 goroutine。服务 goroutine 读取 gRPC 请求,然后调用注册的处理程序来回复它们。当 lis.Accept 因致命错误而失败时,Serve 返回。

对于您的其他问题:

它没有告诉我出了什么问题(除了超时)

这就是问题所在。go test有时间限制,而测试超过了时间。其实没有什么可说的了。它提供了堆栈跟踪,这有助于确定超时的原因,因为它们告诉您每个 goroutine 超时时的位置(例如 goroutine 5 正在等待新连接Listener.Accept)。

似乎也参考了其他库的测试

不是测试(那些将在_test.go文件中),只是代码引用的库中的代码。它们是堆栈跟踪,通常包含来自标准库和/或第三方库的代码,因为它是跟踪时该 goroutine 的调用堆栈的一部分。


查看完整回答
反对 回复 2023-07-10
  • 2 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信