2015-06-06 15 views
12

Attualmente sto cercando di creare alcuni test unitari per l'interfaccia net.Conn in Go, così come altre funzioni che si basano su quella funzionalità, e mi chiedo quale sia il modo migliore per testare le unità in Google Partire? Il mio codice è simile:Come si effettua una prova net.Conn in unit test in Golang?

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

è il modo più efficace di testare questo codice e il codice che utilizza queste funzioni per girare un goroutine separata di agire come server, utilizzare net.http.httptest package, o qualcos'altro?

+1

suggerisco di leggere la fonte per i test per l'attuale ' net' library. Ho raccolto molti consigli facendo ciò in passato. In secondo luogo, come hai già detto, usa il pacchetto 'httptest'. – miltonb

+0

Esistono diverse librerie per * mocking * nei test delle unità, dai un'occhiata a questo post per suggerimenti http://stackoverflow.com/questions/19167970/mock-functions-in-golang – PerroVerd

risposta

4

Anche se dipenderà dai dettagli di implementazione del caso specifico, l'approccio generale sarà quello di avviare un server (in una goroutine separata, come già accennato) e ascoltare le connessioni in entrata.

Ad esempio, supponiamo di girare un server e verificare che il contenuto che stiamo leggendo dal collegamento corrisponda effettivamente a quello che inviamo corso da parte del cliente:

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 
    } 

} 

Si noti che qui non sto iniziando il server nella goroutine, altrimenti il ​​caso di test sarà probabilmente terminato prima che l'ascoltatore abbia eseguito il test.

29

Potreste essere in grado di fare quello che ti serve con net.Pipe che fondamentalmente ti dà entrambe le estremità di una connessione (si pensi, dopo Accetti())

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

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

Questa è la risposta più grande per testare le connessioni tcp senza avviare un server. Dovrebbe essere la risposta accettata o almeno più votata. Grazie! – middlehut

+0

Sì, questo è genio! Non è necessario il sovraccarico di utilizzare effettivamente TCP. In teoria è possibile parallelizzare i test in esecuzione utilizzando questo progetto, poiché non riserva le porte globali dal sistema oprating. –