EDIT: J'ai roulé cette réponse dans un paquet qui rend les choses un peu plus simple - voir ici: https://github.com/jordwest/mock-conn
Alors que la solution d'Ivan travaillera pour simp Dans les cas, gardez à l'esprit qu'une véritable connexion TCP est en fait deux tampons, ou plutôt des tuyaux. Par exemple:
Server | Client
---------+---------
reads <=== writes
writes ===> reads
Si vous utilisez un seul tampon que le serveur à la fois lit et écrit, vous pourriez finir avec le serveur parlant à lui-même.
Voici une solution qui vous permet de transmettre un type MockConn
en tant que ReadWriteCloser
au serveur. Les fonctions Read
, Write
et Close
permettent simplement d'accéder aux fonctions de l'extrémité du serveur.
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,
}
}
Lorsque se moquant d'une connexion « serveur », il suffit de passer le MockConn en place où vous utiliseriez le net.Conn
(ce implémente bien sûr l'interface ReadWriteCloser
seulement, vous pouvez facilement ajouter des méthodes factices pour LocalAddr()
etc si vous avez besoin soutenir l'interface complète net.Conn
)
Dans vos tests, vous pouvez agir en tant que client en lisant et en écrivant aux champs ClientReader
et ClientWriter
au besoin:
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)
}
}
Je suis un peu confus. Le code que vous avez posté ici ne semble pas correspondre à ce que vous avez mis dans github. –