EDITAR: He rodado esta respuesta en un paquete que hace las cosas un poco más simple - ver aquí: https://github.com/jordwest/mock-conn
mientras que la solución de Ivan funcionará para siend En los casos, tenga en cuenta que una conexión TCP real es en realidad dos búferes, o más bien tuberías. Por ejemplo:
Server | Client
---------+---------
reads <=== writes
writes ===> reads
Si utiliza una única memoria intermedia que tanto el servidor lee y escribe en, usted podría terminar con el servidor de hablar a sí mismo.
Aquí hay una solución que le permite pasar un tipo MockConn
como ReadWriteCloser
al servidor. Las funciones Read
, Write
y Close
simplemente realizan un proxy a través de las funciones en el extremo de las canalizaciones del servidor.
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,
}
}
Cuando burlarse de una conexión de 'servidor', sólo tiene que pasar el MockConn en el lugar de donde se usaría el net.Conn
(esto obviamente implementa la interfaz ReadWriteCloser
solamente, usted podría agregar fácilmente métodos ficticias para LocalAddr()
etc si es necesario apoyar la interfaz completa net.Conn
)
En sus pruebas que puede actuar como el cliente mediante la lectura y la escritura en los ClientReader
y ClientWriter
campos según sea necesario:
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)
}
}
Estoy algo confundido. El código que publicaste aquí no parece coincidir con lo que pusiste en github. –