我遇到了conn的奇怪行为。阅读: 让我们假设我有几个用于测试net.Conn的函数:
package example
import (
"io"
"log"
"net"
"os"
"time"
)
func CheckConn(conn net.Conn) (net.Conn, error) {
conn.SetReadDeadline(time.Now())
var one = []byte{}
_, err := conn.Read(one)
if err != nil {
log.Println("Net err: ", err)
}
if err == io.EOF {
return conn, err
}
var zero time.Time
conn.SetReadDeadline(zero)
return conn, nil
}
func CheckConnWithTimeout(conn net.Conn) (net.Conn, error) {
ch := make(chan bool, 1)
defer func() {
ch <- true
}()
go func() {
select {
case <-ch:
case <-time.After(1 * time.Second):
log.Println("It works too long")
os.Exit(1)
}
}()
return CheckConn(conn)
}
我想为它实现测试,让我们从这个开始:
package example
import (
"io"
"net"
"testing"
)
func TestClosedConn(t *testing.T) {
server, client := net.Pipe()
client.Close()
defer server.Close()
_, err := CheckConn(server)
if err != io.EOF {
t.Errorf("Not equal:\nExpected: %v\nactual: %v", io.EOF, err)
}
}
这很好用,我们将从CheckConn函数接收io.EOF,再添加一个测试:
func TestClosedConnAfterWrite(t *testing.T) {
server, client := net.Pipe()
go func() {
client.Write([]byte{0xb})
}()
client.Close()
defer server.Close()
_, err := CheckConn(server)
err = nil
if err != io.EOF {
t.Errorf("Not equal:\nExpected: %v\nactual: %v", io.EOF, err)
}
}
看起来像是第一次测试,但我们在(?)关闭之前写信给客户端。
这不会过去!
conn.Read将返回&amp; errors.errorString {s:“EOF”},而不是io.EOF,因此CheckConn将返回错误== nil,
看起来很奇怪!
但是让我们继续测试,现在我想检查未关闭的连接:
func TestActiveConn(t *testing.T) {
server, client := net.Pipe()
defer client.Close()
defer server.Close()
_, err := CheckConnWithTimeout(server)
if err != nil {
t.Errorf("Not equal:\nExpected: %v\nactual: %v", nil, err)
}
}
我认为你注意到我使用超时函数只是因为在这种情况下SetReadDeadline不起作用(我不明白为什么!)
那么最后两个测试用例出了什么问题?有没有正常的方法来测试连接?为什么SetReadDeadline在这种情况下不起作用?