首页 > 解决方案 > 在 golang 上测试双向 rpc

问题描述

我正在关注一些用于创建双向 grpc 客户端和服务器的教程。客户端将传递一些值,当服务器上的最后一个最大值更改时,它将以当前最大值响应客户端。最后我想写下一些测试用例,但我没有测试场景的经验,这就是为什么我不确定我是否在做正确的事情。

func TestClientConnection(t *testing.T) {

    creds, _ := credentials.NewClientTLSFromFile("../server-cert.pem", "")
    conn, err := grpc.Dial(address, grpc.WithTransportCredentials(creds))
    if err != nil {
        t.Error("Had problem with connection, NOT PASSED")
    }
    defer conn.Close()

    c := proto.NewHerdiusServerClient(conn)

    stream, err := c.CheckMax(context.Background())
    if err != nil {
        t.Error("Had problem with stream, NOT PASSED")
        return
    }

    err = stream.Send(&proto.MaxRequest{Val: int32(10)})
    err = stream.Send(&proto.MaxRequest{Val: int32(12)})
    err = stream.Send(&proto.MaxRequest{Val: int32(13)})
    err = stream.Send(&proto.MaxRequest{Val: int32(9)})

    if err != nil {
        t.Error("Had problem with stream, NOT PASSED")
        return
    }

    return
}

现在当我测试这个场景时go test它通过了,但我也想测试是否从服务器端收到了一些东西。

我的第二个问题是,如果我想将此测试撕裂到不同的场景,例如检查服务器是否连接或流连接或它收到来自服务器端的响应,我该怎么做?我应该创建另一个类来检索连接和流式传输并在测试功能上使用吗?

标签: gogrpc

解决方案


使用 timeout 创建比赛context.WithTimeout,并在流上发送您的数据调用之后Recv。检查您是否在超时内收到任何内容。

具体取决于此处的协议 -Recv如果您必须同时发送服务器数据,您可能需要一个 goroutine。


至于您的第二个问题,Go 的哲学是为每个场景提供清晰、明确、可读的测试。如果某些代码重复也没关系。更重要的是,每个单独的测试都是可读和可理解的。在测试非常重复的情况下,应该使用表驱动测试,但在你描述的情况下,这对我来说听起来像是单独的测试。

进行“构建”功能的测试很有用。一个测试测试连接,另一个连接和发送,另一个连接和发送和接收。这样,当测试失败时,通过单独重新运行它们,您甚至可以在查看测试代码之前非常快速地隔离问题。


推荐阅读