如何在Golang的单元测试中测试net.Conn?

时间:2015-06-06 23:49:14

标签: unit-testing testing tcp go

我目前正在研究为Go中的net.Conn接口创建一些单元测试,以及在该功能之上构建的其他功能,我想知道在单元测试中最好的方法是什么Google Go?我的代码如下:

.225

测试此代码的最有效方法是使用这些函数来启动单独的goroutine以像服务器一样运行,使用net.http.httptest package还是其他什么?

3 个答案:

答案 0 :(得分:56)

您可以使用net.Pipe完成所需的操作,它基本上为您提供连接的两端(想想,在.Accept()之后)

server, client := net.Pipe()
go func() {
  // Do some stuff
  server.Close()
}()

// Do some stuff
client.Close()

答案 1 :(得分:8)

虽然它将取决于您的特定情况的实现细节,但一般方法是启动服务器(在您已经暗示的单独的goroutine中),并监听传入的连接。

例如,让我们启动服务器并验证我们从连接中读取的内容确实是我们从客户端发送的内容:

func TestConn(t *testing.T) {
    message := "Hi there!\n"

    go func() {
        conn, err := net.Dial("tcp", ":3000")
        if err != nil {
            t.Fatal(err)
        }
        defer conn.Close()

        if _, err := fmt.Fprintf(conn, message); err != nil {
            t.Fatal(err)
        }
    }()

    l, err := net.Listen("tcp", ":3000")
    if err != nil {
        t.Fatal(err)
    }
    defer l.Close()
    for {
        conn, err := l.Accept()
        if err != nil {
            return
        }
        defer conn.Close()

        buf, err := ioutil.ReadAll(conn)
        if err != nil {
            t.Fatal(err)
        }

        fmt.Println(string(buf[:]))
        if msg := string(buf[:]); msg != message {
            t.Fatalf("Unexpected message:\nGot:\t\t%s\nExpected:\t%s\n", msg, message)
        }
        return // Done
    }

}

请注意,这里我没有在goroutine中启动服务器,否则测试用例很可能在侦听器运行测试之前完成。

答案 2 :(得分:1)

另一个选择是counterfeiter软件包,它使您可以从接口创建模拟,然后可以存根所需的任何调用。我已经成功地使用它来为我测试Geode的protobuf客户端的net.Conn实例进行存根。

例如-https://github.com/gemfire/geode-go-client/blob/master/connector/protobuf_test.go