为了测试我正在编写的服务器,我希望能够在测试框架中启动和停止它。
为此,我希望我可以将the context package与http.Server结构集成。我希望能够在调用Done
函数时停止服务器并且ctx.Done()
频道会返回一些内容。
我喜欢做的只是修改the http.Server.Serve() method,接受context.Context并检查是否完成,在for循环的每次迭代中,如下所示:
func (srv *server) Serve(ctx context.Context, l net.Listener) error {
defer l.Close()
var tempDelay time.Duration // how long to sleep on accept failure
for {
select {
case <-ctx.Done():
return nil
default:
}
... rest is same as original
然而,似乎我想在for循环中添加该检查,我将不得不重写许多方法,因为此方法调用其他私有方法(如http.server.srv),后者又调用其他方法私人方法....
我还注意到,当侦听器上的Accept()方法返回错误时,for循环将停止。
但是,我似乎无法找到一种方法来让侦听器从它的accept方法输出错误而不访问其私有方法。
如果我必须复制并粘贴一半http库只是为了让服务器停止使用上下文包,我似乎做了一些非常愚蠢和错误的事情。
我知道有很多解决方案支持ServeHTTP功能的上下文取消,但这不是我所说的。我想将一个上下文传递给整个服务器,而不仅仅是每个传入的请求。
这是不可能的吗?
答案 0 :(得分:1)
使用httptest.Server创建一个可以在测试中启动和停止的服务器。
如果直接使用http.Server,则可以通过关闭net.Listener来中断服务循环。当net.Listener关闭时,任何被阻止的Accept操作都将被解除阻塞并返回错误。如果Accept返回永久错误,则Serve函数返回。