2015-06-06 32 views
12

Tôi hiện đang xem xét việc tạo ra một số xét nghiệm đơn vị cho giao diện net.Conn tại Gò, cũng như các chức năng khác mà xây dựng trên đầu trang của các chức năng đó, và tôi tự hỏi cách tốt nhất để kiểm tra đơn vị là những gì mà trong Google Đi? Mã của tôi trông giống như:Làm thế nào để kiểm tra net.Conn trong các bài kiểm tra đơn vị trong Golang?

conn, _:=net.Dial("tcp", "127.0.0.1:8080") 
... 
fmt.Fprintf(conn, "test") 
... 
buffer:=make([]byte, 100) 
conn.Read(buffer) 

có phải là cách hiệu quả nhất của kiểm tra mã này và mã có sử dụng các chức năng này để quay về một goroutine riêng biệt để hoạt động giống như máy chủ, sử dụng net.http.httptest package, hay cái gì khác?

+1

Đề nghị đọc nguồn cho các cuộc thử nghiệm cho thực tế ' net' thư viện. Tôi đã nhặt rất nhiều lời khuyên bằng cách làm điều đó trong quá khứ. Thứ hai, như bạn đã đề cập, sử dụng gói 'httptest'. – miltonb

+0

Có một số thư viện cho * mocking * trong kiểm tra đơn vị, hãy xem bài viết này cho gợi ý http://stackoverflow.com/questions/19167970/mock-functions-in-golang – PerroVerd

Trả lời

4

Mặc dù nó sẽ phụ thuộc vào chi tiết thực hiện của trường hợp cụ thể của bạn, cách tiếp cận chung sẽ là khởi động máy chủ (trong một goroutine riêng biệt, như bạn đã gợi ý) và lắng nghe các kết nối đến.

Ví dụ, chúng ta hãy quay lên một máy chủ và xác minh rằng các nội dung chúng tôi đang đọc từ kết nối thực sự là những gì chúng tôi gửi qua từ khách hàng:

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 
    } 

} 

Lưu ý rằng ở đây tôi không khởi động máy chủ trong goroutine, nếu không thì trường hợp kiểm tra có thể được hoàn thành trước khi người nghe đã chạy thử nghiệm.

29

Bạn có thể có thể làm những gì bạn cần với net.Pipe mà về cơ bản mang đến cho bạn cả hai đầu của một kết nối (suy nghĩ, sau .Đồng ý())

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

// Do some stuff 
client.Close() 
+5

Đây là câu trả lời lớn nhất cho các kết nối thử nghiệm tcp mà không cần khởi động máy chủ. Nên là sự chấp nhận hoặc ít nhất là nhiều câu trả lời được trả lời bình chọn. Cảm ơn bạn! – middlehut

+0

Vâng, đây là thiên tài! Bạn không cần phí trên thực tế khi sử dụng TCP. Bạn có thể trong lý thuyết song song các bài kiểm tra của bạn chạy bằng cách sử dụng thiết kế này, vì nó không dự trữ các cổng toàn cầu từ hệ thống oprating. –

Các vấn đề liên quan