Simulate TCP connection in Go

In Go, the TCP connection (net.Conn) is io.ReadWriteCloser. I would like to test my network code by simulating a TCP connection. There are two requirements that I have:

  • reading data is stored in a string
  • whenever data is written, I would like it to be stored in some kind of buffer that I can access later

Is there a data structure for this or an easy way to create it?

+5
source share
3 answers

Why not use bytes.Buffer? This is a io.ReadWriterand has a method Stringfor retrieving stored data. If you need to do this io.ReadWriteCloser, you can define your own type:

type CloseableBuffer struct {
    bytes.Buffer
}

Close:

func (b *CloseableBuffer) Close() error {
    return nil
}
+3

. , - . : https://github.com/jordwest/mock-conn


Ivan , , TCP- , , . :

 Server   |   Client
 ---------+---------
  reads <===  writes
 writes ===>  reads

, , , .

, MockConn ReadWriteCloser . Read, Write Close .

type MockConn struct {
    ServerReader *io.PipeReader
    ServerWriter *io.PipeWriter

    ClientReader *io.PipeReader
    ClientWriter *io.PipeWriter
}

func (c MockConn) Close() error {
    if err := c.ServerWriter.Close(); err != nil {
        return err
    }
    if err := c.ServerReader.Close(); err != nil {
        return err
    }
    return nil
}

func (c MockConn) Read(data []byte) (n int, err error)  { return c.ServerReader.Read(data) }
func (c MockConn) Write(data []byte) (n int, err error) { return c.ServerWriter.Write(data) }

func NewMockConn() MockConn {
    serverRead, clientWrite := io.Pipe()
    clientRead, serverWrite := io.Pipe()

    return MockConn{
        ServerReader: serverRead,
        ServerWriter: serverWrite,
        ClientReader: clientRead,
        ClientWriter: clientWrite,
    }
}

"", MockConn , net.Conn (, , ReadWriteCloser, LocalAddr() .., net.Conn)

, ClientReader ClientWriter :

func TestTalkToServer(t *testing.T) {
    /*
     * Assumes that NewMockConn has already been called and
     * the server is waiting for incoming data
     */

    // Send a message to the server
    fmt.Fprintf(mockConn.ClientWriter, "Hello from client!\n")

    // Wait for the response from the server
    rd := bufio.NewReader(mockConn.ClientReader)
    line, err := rd.ReadString('\n')

    if line != "Hello from server!" {
        t.Errorf("Server response not as expected: %s\n", line)
    }
}
+5

, , , , net.Pipe(), net.Conn,

+2

All Articles