如何为测试创建两个相连的io.ReadWriteCloser实例?
问题:如何创建两个相连的io.ReadWriteCloser用于测试
我正在为自己的网络应用编写测试,希望避免为每个测试创建套接字,因此考虑使用标准库中的io.Pipe。但它仅提供io.PipeReader与io.PipeWriter的配对,而我需要两个相连的io.ReadWriteCloser。测试代码如下:
func TestEndpoints() { // 创建pipeEndpoint1和pipeEndpoint2,二者需实现io.ReadWriteCloser e1 := makeEndpoint(pipeEndpoint1) e2 := makeEndpoint(pipeEndpoint2) // 执行测试 } func makeEndpoint(rwc io.ReadWriteCloser) *Endpoint { // }
请问是否有办法创建两个相连的io.ReadWriteCloser?
解决方案
可以通过组合两对io.Pipe来实现双向连接的io.ReadWriteCloser,核心思路是将两对单向管道的读写端交叉绑定,形成双向通信通道。
实现代码
// createConnectedRWCs 返回两个双向连通的io.ReadWriteCloser func createConnectedRWCs() (io.ReadWriteCloser, io.ReadWriteCloser) { // 创建两对单向管道 pipe1R, pipe1W := io.Pipe() pipe2R, pipe2W := io.Pipe() // 自定义结构体实现io.ReadWriteCloser type bidirectionalPipe struct { io.Reader io.Writer closeFn func() error } func (p *bidirectionalPipe) Close() error { return p.closeFn() } // 组装第一个双向端点:读来自pipe1R,写往pipe2W rwc1 := &bidirectionalPipe{ Reader: pipe1R, Writer: pipe2W, closeFn: func() error { var err error if cerr := pipe1R.Close(); cerr != nil { err = cerr } if cerr := pipe2W.Close(); cerr != nil && err == nil { err = cerr } return err }, } // 组装第二个双向端点:读来自pipe2R,写往pipe1W rwc2 := &bidirectionalPipe{ Reader: pipe2R, Writer: pipe1W, closeFn: func() error { var err error if cerr := pipe2R.Close(); cerr != nil { err = cerr } if cerr := pipe1W.Close(); cerr != nil && err == nil { err = cerr } return err }, } return rwc1, rwc2 }
在测试中使用
func TestEndpoints() { pipeEndpoint1, pipeEndpoint2 := createConnectedRWCs() defer pipeEndpoint1.Close() defer pipeEndpoint2.Close() e1 := makeEndpoint(pipeEndpoint1) e2 := makeEndpoint(pipeEndpoint2) // 执行测试逻辑 }
这样两个端点就能实现双向通信:pipeEndpoint1写入的数据可以从pipeEndpoint2读取,反之亦然。关闭端点时会同时关闭关联的所有管道端,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Anton Lahti
相关产品推荐
相关产品推荐

